スキップしてメイン コンテンツに移動

ドコモIDでOpenID認証してみる

Google App Engineでは、簡単にOpenID認証できる仕組みがある。

今回は、ドコモID(OpenID)を使ってユーザー認証させてみた。



アプリケーションの設定

GAEのアプリケーション設定で、Authentication Typeを「Federated Login」に変更する。

認証が必要なページの指定

認証が必要なページは、app.yamlのスクリプトハンドラ(login: required)で指定できる。今回は/member/配下のパスについては認証が必要としてみた。

app.yaml
- url: /member/(.*)
  script: controllers.front.member.application
  secure: optional
  login: required

認証要求ページの作成

非ログイン状態で、認証が必要なページにアクセスされると /_ah/login_required へリダイレクトされる。なので、app.yamlにこのパスについてのスクリプトハンドラを指定しておき、「認証が必要です。どのプロバイダでログインする?」的なページを作成しておく。 使用するOpenIDプロバイダが1種類の場合は、このスクリプトでログインURLへリダイレクトさせても良いだろう。

app.yaml
- url: /_ah/login_required
  script: controllers.front.system.application
  secure: optional

ログインURLの取得

ログインURLは、以下の関数で取得できる。今回はドコモIDを使用する。federated_identityには各OpenIDプロバイダで指定されている OP Identifier を指定する。dest_urlにはログイン後に遷移するパスを指定しておく。

ログインURLの取得
from google.appengine.api import users

docomo_url = users.create_login_url( dest_url='/', federated_identity='https://i.mydocomo.com' )

XRDS文書の設置

ログイン時、OpenIDプロバイダによっては、アプリケーションサイト側に設置されたXRDS文書を参照しに来る。XRDS文書のパスは /_ah/xrds となっているため、app.yamlにスクリプトハンドラを設定しておく。今回はスクリプトにハンドリングしたが、静的ファイルとして設置しても問題ない。

app.yaml
- url: /_ah/(xrds|login_required)
  script: controllers.front.system.application
  secure: optional

返却するXRDS文書。これはOpenIDプロバイダによって公開されている。

返却するXRDS文書
<!--xml version="1.0" encoding="UTF-8"?--><br /> <xrds:XRDS xmlns:xrds="xri://$xrds" xmlns:openid="http://openid.net/xmlns/1.0" xmlns="xri://$xrd*($v*2.0)"><br /> <xrd><br /> <service priority="0"><br /> <type>http://specs.openid.net/auth/2.0/return_to</Type><br /> <uri>https://gcp-memo.appspot.com/</URI><br /> </Service><br /> </XRD><br /> </xrds:XRDS><br />

以上。

ログインURLにアクセスすると、ドコモ側のログイン画面が表示され、認証が必要なページにアクセスすることができる。

その他、mixi、Google、MySoftbankIDでも認証させることができた。

ただし、ドキュメント上OpenIDのサポートは「Experimental(実験的)」となっている。随分昔からこのままなので正式版にはならないかもしれない。そもそもOpenID自体がもうすでにオワコンな感じだけど。

コメント

このブログの人気の投稿

Moduleをdispach.yamlで振り分ける方法

Google App Engineには、アプリケーション内の機能をグループ化できる Modules というしくみがある。Moduleごとに、インスタンスのスペックやスケールのルールが設定できるため、フロントエンドとバックオフィス、バックグラウンドジョブといった用途別にModuleを作成すると良さそうだ。また、どのModuleが使われるかは、URL(パス)で振り分けることができる。今回はその方法のメモ。 Moduleのyamlファイルの作成 今回は、以下の3つのModuleを作ってみる。 ・フロントエンド用(app.yaml) default ・バックオフィス用(back.yaml) ・JOB用(job.yaml) まずは各Moduleのyamlファイルを作成する。 app.yaml application: gcp-memo module: default version: 1 runtime: python27 api_version: 1 threadsafe: true instance_class: F1 (以下省略) admin.yaml application: gcp-memo module: admin version: 1 runtime: python27 api_version: 1 threadsafe: true instance_class: F1 (以下省略) job.yaml application: gcp-memo module: job version: 1 runtime: python27 api_version: 1 threadsafe: true instance_class: B1 basic_scaling: max_instances: 2 idle_timeout: 10m (以下省略) dispatch.yamlファイルの作成 続いて、これらのModuleを振り分けるdispatch.yamlを作成する。今回は、パスが/admin/に一致すればadminモジュールへ、/job/に一致すればjobモジュールが使用されるようにする。dispatch.yamlは、アプリケーションのルートディレクトリに配置する必要がある。Moduleのyamlファイルについては、ルート...

Managed Virtual Machine に望むこと

先日2014年4月22日に行われた、Google Cloud Platformセッションの模様がYoutubeに公開されてた。 地方民はこういうイベントになかなか参加できないので、動画配信はほんとに助かる。ありがたや。。。 動画の中で語られている Managed VM は地味だけど、なにげにすごい機能だと思う。GAEでできなかったほとんどの事がこれで解決できるかもしれない。 ただ、個人的に Managed VMでは、(スケールアウトしなくていいので)固定IPも使えるようになってほしい。なぜなら、Google App Engineで外部のシステムと連携するとき、相手側でIPアドレス制限されている事がある。だから、連携前にあらかじめこちらのIPアドレスを教えておくのだけど、GAEはPaaSなのでその範囲も広いし、いつ変わるかわからない。まぁ、IPアドレス制限という方法自体がすでに時代遅れな感じではあるけど。 ともかく、GAEではそういうシステムと連携する時は、間にGAEでないサーバーを中継させておく必要がある。なので、このためだけにOSやApacheのメンテが発生する。これは、ほんとにアホらしいことだ。もし、Managed VMで固定IPが使えれば、対外部システムとの処理だけそのインスタンスで行えばいいし、中継サーバーも不要になるので、だいぶ楽になるのだ。 Googleさん、よろしくおねがいします。

Google App Engineでファイルを保存する方法3つ

Google App Engineでは、通常のWebアプリケーションのように、サーバー上のファイルシステムへアクセスすることができない。別の方法でファイルの読み書きをする事になるけど、方法はいくつかあるので、それぞれの方法と長所短所をまとめてみた。サンプルと全てのソースコードはこちら。( サンプル / ソースコード ) 方法1:BlobPropertyを使う ndb(db)のBlobProperty(https://developers.google.com/appengine/docs/python/ndb/properties)ではバイナリデータをそのまま格納できる。 まずは保存するModelの定義を実装する。 from google.appengine.ext import ndb class UserFileModel(ndb.Model):     """     ファイル格納モデル     """     file_data = ndb.BlobProperty()                  # ファイルデータ 続いて、アップロードフォーム。 <form> <div class="form-group"> <input id="exampleInputFile" name="file_data" type="file" />     </div> <button class="btn btn-default" type="submit">保存</button> </form> アップロードハンドラを実装。リクエストされたデータをそのまま突っ込むだけ。 def post(self):         file_data = self.request.get('file_data')         user_file = UserFileMod...