そろそろ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を使う場合の処理シーケンスをおおざっぱに言うと、以下のようになります。
- tweepy.OAuthHandlerにConsumerKey、ConsumerSecret, RequestToken, ユーザの認証を示すVerifierを食わせてaccess tokenを得る
- tweepy.APIを作成する際に1のOAuthHandlerを食わせて、認証済みAPIオブジェクトを作成する
- 認証済みAPIオブジェクトを使って各種API呼出しを行う
access tokenがあれば認証済みOAuthHandlerを再構築できるので,僕はセッションIDをキーにaccess tokenをmemcacheに保存しています。@ITの入門記事やoauthの仕様と見比べながら読むと理解が早いかもしれません。
またセッション周りについては先ほどの記事のsimple_cookieを使用しています。
関連する記事
タグ: google app engine, python, tweepy




