tweepyでtwitterの3-legged OAuth認証を試してみた(GoogleAppEngine)

そろそろGAE上でユーザ登録が必要なサービスを作りたいのですが、ユーザ登録周りの実装はやりたくないので、twitterのOAuthを代わりに使ってみる事にしました。twitterのAPIを叩くのにこれまではtwythonを使っていたのですが,OAuthに対応していなかったので、今回はtweepyを使います。以前2-legged OAuthを試してみましたが、今回は3-legged OAuthです。

twitterのOAuth認証によるログイン、ログアウトとログイン後にユーザのタイムライン表示と、tweetを実装しています。ロジックのソースは以下になりますが、まず動作しているサンプルを見るのが早いと思います。

# -*- coding: utf-8 -*-

import os
import cgi
import logging

from google.appengine.ext.webapp import template
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext import db
import wsgiref.handlers

from google.appengine.api import memcache 
import uuid
import tweepy
from simple_cookie2 import Cookies

CONSUMER_KEY    = 'your consumer key'
CONSUMER_SECRET = 'your consumer secret'
CALLBACK_URL    = 'http://127.0.0.1:8080/oauth_cb'
SESSION_EXPIRE  = 300

# ユーザがtwitter認証を行う際のリクエストトークンを保持するモデル
class RequestToken(db.Model):
  token_key    = db.StringProperty(required=True)
  token_secret = db.StringProperty(required=True)

# ログインしている場合はタイムライン表示
class Home(webapp.RequestHandler):
  def get(self):
    cookie = Cookies(self, max_age=SESSION_EXPIRE)
    if not cookie.has_key('sid'):
      cookie['sid'] = str(uuid.uuid4())   # セッション開始

    (timeline, username) = (None, None)
    access_token = memcache.get(cookie['sid'])
    if access_token:
      auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
      auth.set_access_token(access_token.key, access_token.secret)
      username = auth.get_username()
      api = tweepy.API(auth_handler=auth)
      timeline = api.home_timeline(count=10)
    self.response.out.write(template.render('timeline.html', {'username':username, 'timeline': timeline}))

# tweet
class Update(webapp.RequestHandler):
  def post(self):
    cookie = Cookies(self)
    access_token = memcache.get(cookie['sid'])
    if access_token:
      auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
      auth.set_access_token(access_token.key, access_token.secret)
      api = tweepy.API(auth_handler=auth)
      api.update_status(status=self.request.get('status'))
    self.redirect('/')

# twitterのOAuth認証
class OAuth(webapp.RequestHandler):
  def get(self):
    auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET, CALLBACK_URL)
    auth_url = auth.get_authorization_url()
    request_token = RequestToken(token_key=auth.request_token.key, token_secret=auth.request_token.secret)
    request_token.put()
    self.redirect(auth_url)   # twitterの認証画面へリダイレクト

# twitterのOAuth認証後のコールバック
class OAuthCB(webapp.RequestHandler):
  def get(self):
    request_token_key = self.request.get("oauth_token")
    request_verifier  = self.request.get('oauth_verifier')
    auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
    request_token = RequestToken.gql("WHERE token_key=:1", request_token_key).get()
    auth.set_request_token(request_token.token_key, request_token.token_secret)
    access_token = auth.get_access_token(request_verifier)
    cookie = Cookies(self)
    memcache.set(cookie['sid'], access_token, SESSION_EXPIRE)
    self.redirect('/')

# ログアウト
# twitter認証側のCookieはいじれないのでセッションを削除する
class Logout(webapp.RequestHandler):
  def get(self):
    cookie = Cookies(self)
    if cookie.has_key('sid'):
      memcache.delete(cookie['sid'])
      del cookie['sid']
    self.redirect('/')

application = webapp.WSGIApplication(
  [
    ('/', Home),
    ('/update', Update),
    ('/logout',   Logout),
    ('/oauth',    OAuth),
    ('/oauth_cb', OAuthCB),
  ],
  debug=True)

if __name__ == "__main__":
  run_wsgi_app(application)

少しややこしいですね。tweepyはよく作られたライブラリなので、一度ソースを読んでみる事をお薦めしますが、OAuth認証が必要なtwitter apiを使う場合の処理シーケンスをおおざっぱに言うと、以下のようになります。

  1. tweepy.OAuthHandlerにConsumerKey、ConsumerSecret, RequestToken, ユーザの認証を示すVerifierを食わせてaccess tokenを得る
  2. tweepy.APIを作成する際に1のOAuthHandlerを食わせて、認証済みAPIオブジェクトを作成する
  3. 認証済みAPIオブジェクトを使って各種API呼出しを行う

access tokenがあれば認証済みOAuthHandlerを再構築できるので,僕はセッションIDをキーにaccess tokenをmemcacheに保存しています。@ITの入門記事oauthの仕様と見比べながら読むと理解が早いかもしれません。

またセッション周りについては先ほどの記事のsimple_cookieを使用しています。

1 thought on “tweepyでtwitterの3-legged OAuth認証を試してみた(GoogleAppEngine)”

Leave a Reply

Your email address will not be published. Required fields are marked *