2008年8月21日木曜日

Google App Engine: mixi OpenIDで認証する

このブログ記事をはてなブックマークに追加

mixiがOpenIDに対応したということで早速Google App Engineで実装してみた。以前のエントリで紹介したがGoogle App Engineのサンプル集OpenID ConsumerというWebアプリがあるので、そのソースコードを利用させてもらった。

しかし、実際に使ってみればわかるのだがこのコードにはいくつかのバグ(とGoogle App Engineの制限)があってちゃんと動かない。下記のリンク先は正常に動くように修正したものだ。

mixi OpenID テスト

以下にバグの箇所とその修正コードを示す。

consumer.py

344-345行目の以下のコードを

self.response.set_status(302) self.response.headers['Location'] = redirect_url

以下のように修正する。

self.response.out.write("<html><head><meta http-equiv=\"refresh\" content=\"0;url=%s\"></head><body></body></html>" % (redirect_url,))

これはGoogle App Engineの制限を回避するためで、一度HTMLを表示し同時にリダイレクトを行っている。

fetcher.py

以下の57行目からのコードで、青で示したコードの後ろにある赤で示したコードを青のコードの前に移動させる。

if body: method = urlfetch.POST if 'Content-Type' not in headers: headers['Content-Type'] = 'application/x-www-form-urlencoded' else: method = urlfetch.GET if not headers: headers = {}

また、外部モジュールのPython OpenID Library (openid)ElementTree (elementtree)は最新のものに変更しても問題なく動く。

ローカルでテストする際はPython OpenID Libraryに付属するexamples/server.pyを利用するのが便利だ。dev_appserver.pyを起動させた後、以下のようにOpenIDサーバを起動させる。これによりテスト用のOpenIDをローカルで作成できる。

./examples/server.py -s localhost

http://localhost:8000/ をブラウザで開くとログイン画面が出るので適当な名前を入れる(たとえばtest)。これでhttp://localhost:8000/id/test がOpenIDのURLとなる。その後、http://localhost:8080/ を開き、OpenIDの入力フィールドでこのIDを使うことができる。もちろんローカルのOpenIDではなくmixi OpenIDや他のOpenIDを使うこともできる。

もしWindowsを使っていてElementTree関連のエラーが出た場合、正しくpyexpatモジュールが読み込まれていない可能性がある。その場合、PythonディレクトリにあるDLLsディレクトリからpyexpat.pydを持ってくると直るかもしれない。

その他については簡単な日本語訳やmixi OpenIDのログインボタンの表示などでそれほど難しくはない。マイミクシィ認証やコミュニティ認証もClaimed Identifierを変更するだけなのでそんなに手間ではないはず。しかし今回、Google App Engineの制限やコードのバグで思ったよりも手間取ってしまった。それでも、ちゃんと動いてしまいさえすればいろいろと応用できそうだ。

追記:

ログイン履歴についてはセキュリティを考慮して最初の1文字以外は伏字とし、リンクしないように変更した。

追記2:

ログイン後にコメントを残せるように変更した。

2 コメント:

匿名 さんのコメント...

現在のGAEであれば、ダウンロードしたままのコードで動くようです。

コードは修正無しで動くのですが、index.yamlの「kind: Login」に関する行をコメントアウトする必要がありました。

もしよろしければ、ご確認いただき、エントリーに追記していただけると幸いです。

nox さんのコメント...

コメントありがとうございます。

現在ではGAE側でリダイレクトの制限がなく、また、ソースコードも最新版があるのですね。

index.yamlの件は、データストアのインデックス設定をしているだけだと思うのですが、コメントアウトではなく、index.yaml自体を削除するのではダメでしょうか。このファイルは実行時に自動生成されると思うので。

それとも生成されたindex.yamlで動作しないと言うことなのでしょうか。