今回はGoogle App Engine上でOAuth認証をして、
GoogleAppEngineLauncherのメニューからFile=>"Add Existing Application..."を選択して、OAUTH_
とOAUTH_
を、
![EDAM OAuthデモ EDAM OAuthデモ](/assets/images/dev/serial/01/evernote_api/0012/001.png)
ポート番号を8081以外にする場合は、APP_
の番号を変更すれば良いです。また、
Google App Engineでは、
- evernote
- thrift
- python-oauth2
- httplib2
- gaeutilities
evernoteとthriftはeverenote-api-1.
今回は説明を簡単にするためにセッションによってOAuthの情報を管理するようにしています。Googleアカウントなどに紐付けて管理というのでも良いでしょう。
では、OAuthTokenHandler
クラスに処理が渡されます。
class OAuthTokenHandler(webapp.RequestHandler):
"""OAuthの認証手続き"""
def get(self):
## Webアプリケーション用キーの設定
consumer = oauth.Consumer(key=OAUTH_CONSUMER_KEY, secret=OAUTH_CONSUMER_SECRET)
## トークン取得後にOAuthサーバから転送してもらうURIの設定
params = { "oauth_callback": TOKEN_CALLBACK_URI }
## 最初の要求作成: この段階ではトークンはなし
request = oauth.Request.from_consumer_and_token(
consumer, token=None, http_method="GET", http_url=TOKEN_URI, parameters=params)
## 署名作成
request.sign_request(oauth.SignatureMethod_HMAC_SHA1(), consumer, None)
## 最初の要求
uri = request.to_url()
result = urlfetch.fetch(uri)
if result.status_code != 200:
self.redirect("/error")
return
## レスポンスから仮証明(リクエストトークン)を抽出
token = oauth.Token.from_string(result.content)
## OAuthサーバのユーザの認証・同意画面に飛ばす
request = oauth.Request.from_token_and_callback(
token=token, callback=TOKEN_CALLBACK_URI, http_url=AUTHORIZATION_URI)
uri = request.to_url()
self.redirect(uri)
まず、oauth_
で指定しておきます。また、
成功するとOAuthサーバから仮証明(以前のリクエストトークンに相当)の情報が返ってきます。次に、
![OAuthログイン画面 OAuthログイン画面](/assets/images/dev/serial/01/evernote_api/0012/thumb/TH800_002.png)
ここでユーザ名・
![OAuth承認画面 OAuth承認画面](/assets/images/dev/serial/01/evernote_api/0012/thumb/TH800_003.png)
ユーザが承認した場合は、OAuthTokenCallbakHandler
クラスで行っています。
class OAuthTokenCallbackHandler(webapp.RequestHandler):
"""OAuthから戻ってきた後の処理"""
def get(self):
session = sessions.Session()
## ユーザが承認した場合はoauth_tokenとoauth_verifierが返ってくる
oauth_token = self.request.get("oauth_token")
oauth_verifier = self.request.get("oauth_verifier")
## シークレットは使用しないので空で良い
token = oauth.Token(oauth_token, "")
## oauth_verifierは必須
token.set_verifier(oauth_verifier)
## トークン証明(アクセストークン)の取得
consumer = oauth.Consumer(key=OAUTH_CONSUMER_KEY, secret=OAUTH_CONSUMER_SECRET)
client = oauth.Client(consumer, token)
## oauth.SignatureMethod_HMAC_SHA1()では動かない (要確認?)
client.set_signature_method(oauth.SignatureMethod_PLAINTEXT())
response, content = client.request(TOKEN_URI)
if response.status != 200:
self.redirect("/error")
return
## トークン証明(アクセストークン)などの抽出
## NoteStoreにアクセスするのに必要なのでセッションとして保持
params = parse_qs(content)
session["oauth_token"] = params["oauth_token"][0]
session["edam_shard"] = params["edam_shard"][0]
session["edam_userId"] = params["edam_userId"][0]
self.redirect("/")
ユーザ承認済の仮証明 oauth_
トークン証明の取得が終わったら一度トップページに飛ぶようにしています。トークン証明が正常に保存されている場合は、
![承認後のトップページ 承認後のトップページ](/assets/images/dev/serial/01/evernote_api/0012/004.png)
ノートブック一覧の処理は以下のListHandler
クラスで行っています。
class ListHandler(webapp.RequestHandler):
"""ノートブックの一覧を表示"""
def get(self):
session = sessions.Session()
## 必要なデータがセッション内にあることを確認
for key in ["oauth_token", "edam_shard", "edam_userId"]:
if key not in session or session[key] == "":
sys.stderr.write('OAuth認証を先に行う必要があります。\n')
self.redirect("/error")
return
## NoteStoreからnotebooksを取得
notestore_uri = NOTESTORE_BASE_URI + session["edam_shard"]
notestore_http_client = THttpClient.THttpClient(notestore_uri)
notestore_protocol = TBinaryProtocol.TBinaryProtocol(notestore_http_client)
notestore = NoteStore.Client(notestore_protocol)
notebooks = notestore.listNotebooks(session["oauth_token"])
self.response.out.write('<html><head><title>ノートブック一覧</title></head>')
self.response.out.write('<body><h1>ノートブック一覧</h1>')
self.response.out.write('<p>%d個のノートブック</p><ul>' % len(notebooks))
for notebook in notebooks:
self.response.out.write('<li>%s</li>' % notebook.name)
self.response.out.write('</ul><p><a href="/">トップページに戻る</a></p></body></html>')
Evernoteにおいては、
![ノートブック一覧 ノートブック一覧](/assets/images/dev/serial/01/evernote_api/0012/005.png)
今回はGoogle App Engine上においてOAuth認証経由でのEvernote APIの使い方を説明しました。次回も引き続きGoogle App Engineでの開発を解説します。