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:
ログイン後にコメントを残せるように変更した。
しかし、実際に使ってみればわかるのだがこのコードにはいくつかのバグ(と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:
ログイン後にコメントを残せるように変更した。
コメント
コードは修正無しで動くのですが、index.yamlの「kind: Login」に関する行をコメントアウトする必要がありました。
もしよろしければ、ご確認いただき、エントリーに追記していただけると幸いです。
現在ではGAE側でリダイレクトの制限がなく、また、ソースコードも最新版があるのですね。
index.yamlの件は、データストアのインデックス設定をしているだけだと思うのですが、コメントアウトではなく、index.yaml自体を削除するのではダメでしょうか。このファイルは実行時に自動生成されると思うので。
それとも生成されたindex.yamlで動作しないと言うことなのでしょうか。