- 「GoogleのOpenIDってrealm単位で変わるんですよねー。」
- 「いわゆるPPIDですよね。他のサイトと識別子変えてくれるので名寄せできないんですよ。」
- 「ドメイン変わったときにユーザー引き継ぎたいときはどうすれば?Gmail(メアド)でむりやりつなぐしかない?」
この話は前からありましたが、最近Janrain Engage (formerly RPX)を久々に使ったら、GoogleのユニークなIdentifierっぽいのが取れました。
そのOpenID AuthNリクエストからその取得方法を調べました。
※Janrain EngageってのはシンプルなAPIで簡単にOpenIDのRPやtwitter/facebookのOAuth Cnsumer/Clientになれちゃうサービス?プロダクト?です。
Janrain Engageの仕様などについてはここでは触れません。
振り返り;OpenIDのフローでGoogleから渡されるUser Identifier
まずはこの部分の復習です。
まずは、最低限のOpenIDのAuthNリクエストを送ってみます。
【Request】
https://www.google.com/accounts/o8/ud? &openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0 &openid.mode=checkid_setup &openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select &openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select &openid.realm=http%3A%2F%2Frp.example.com%2F &openid.return_to=http%3A%2F%2Frp.example.com%2Freturn_to
※ちなみに、rp.example.comってのは存在しません。
同意画面の後に、こんなレスポンスが返ってきます。
【Response】
http://rp.example.com/return_to? openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0 &openid.mode=id_res &openid.op_endpoint=https%3A%2F%2Fwww.google.com%2Faccounts%2Fo8%2Fud &openid.response_nonce=(nonceの値) &openid.return_to=http%3A%2F%2Frp.example.com%2Freturn_to &openid.assoc_handle=(Assoc Handleの値) &openid.signed=op_endpoint%2Cclaimed_id%2Cidentity%2Creturn_to%2Cresponse_nonce%2Cassoc_handle &openid.sig=(Signatureの値) &openid.identity=https%3A%2F%2Fwww.google.com%2Faccounts%2Fo8%2Fid%3Fid%3DAItOawlgrB6aWhb9_h3D_N6aSOsyFbQNsak5ej0 &openid.claimed_id=https%3A%2F%2Fwww.google.com%2Faccounts%2Fo8%2Fid%3Fid%3DAItOawlgrB6aWhb9_h3D_N6aSOsyFbQNsak5ej0
リクエストのopenid.realmパラメータを変更すると、このopenid.claimed_idの/id/以降の文字列が変わります。
私のアカウントを晒すと、こんな感じでした。
- http://rp.example.com/ : AItOawlgrB6aWhb9_h3D_N6aSOsyFbQNsak5ej0
- http://rp2.example.com/ : AItOawkIYyIzr6aa3CtLAlL4ESBi-2ytKUGcEfY
これがrealmベースのPPIDってやつですね。
秘密の?AXパラメータによる識別子取得方法
ずばり、こんな感じです。
"http://schemas.openid.net/ax/api/user_id"というAXのパラメータを追加する
それでは実践してみましょう。
正式な実装方法は書いていませんでしたが、いろいと組み合わせた結果、こんな感じでいけそうでした。
【Request】
https://www.google.com/accounts/o8/ud?openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0 &openid.mode=checkid_setup &openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select &openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select &openid.realm=http%3A%2F%2Frp.example.com%2F &openid.return_to=http%3A%2F%2Frp.example.com%2Freturn_to &openid.ns.ax=http%3A%2F%2Fopenid.net%2Fsrv%2Fax%2F1.0 &openid.ax.mode=fetch_request &openid.ax.required=email%2Cguid &openid.ax.type.email=http%3A%2F%2Faxschema.org%2Fcontact%2Femail &openid.ax.type.guid=http%3A%2F%2Fschemas.openid.net%2Fax%2Fapi%2Fuser_id
この行がポイントです。
&openid.ax.type.guid=http%3A%2F%2Fschemas.openid.net%2Fax%2Fapi%2Fuser_id
これでレスポンスを見てみます。
【Response : rp.example.com】
http://rp.example.com/return_to?openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0 &openid.mode=id_res &openid.op_endpoint=https%3A%2F%2Fwww.google.com%2Faccounts%2Fo8%2Fud &openid.response_nonce=(nonceの値) &openid.return_to=http%3A%2F%2Frp.example.com%2Freturn_to &openid.assoc_handle=(Assoc Handleの値) &openid.signed=op_endpoint%2Cclaimed_id%2Cidentity%2Creturn_to%2Cresponse_nonce%2Cassoc_handle%2Cns.ext1%2Cext1.mode%2Cext1.type.guid%2Cext1.value.guid%2Cext1.type.email%2Cext1.value.email &openid.sig=(Signatureの値) &openid.identity=https%3A%2F%2Fwww.google.com%2Faccounts%2Fo8%2Fid%3Fid%3DAItOawlgrB6aWhb9_h3D_N6aSOsyFbQNsak5ej0 &openid.claimed_id=https%3A%2F%2Fwww.google.com%2Faccounts%2Fo8%2Fid%3Fid%3DAItOawlgrB6aWhb9_h3D_N6aSOsyFbQNsak5ej0 &openid.ns.ext1=http%3A%2F%2Fopenid.net%2Fsrv%2Fax%2F1.0 &openid.ext1.mode=fetch_response &openid.ext1.type.guid=http%3A%2F%2Fschemas.openid.net%2Fax%2Fapi%2Fuser_id &openid.ext1.value.guid=(グローバルユニークなユーザー識別子) &openid.ext1.type.email=http%3A%2F%2Faxschema.org%2Fcontact%2Femail &openid.ext1.value.email=(メアド)
こんな感じで、(グローバルユニークなユーザー識別子)が返ってきます。
realmとreturn_toのドメインをrp2.example.comに変えてみます。
【Response : rp2.example.com】
http://rp.example.com/return_to?openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0 &openid.mode=id_res &openid.op_endpoint=https%3A%2F%2Fwww.google.com%2Faccounts%2Fo8%2Fud &openid.response_nonce=(nonceの値) &openid.return_to=http%3A%2F%2Frp2.example.com%2Freturn_to &openid.assoc_handle=(Assoc Handleの値) &openid.signed=op_endpoint%2Cclaimed_id%2Cidentity%2Creturn_to%2Cresponse_nonce%2Cassoc_handle%2Cns.ext1%2Cext1.mode%2Cext1.type.guid%2Cext1.value.guid%2Cext1.type.email%2Cext1.value.email &openid.sig=(Signatureの値) &openid.identity=https%3A%2F%2Fwww.google.com%2Faccounts%2Fo8%2Fid%3Fid%3DAItOawkIYyIzr6aa3CtLAlL4ESBi-2ytKUGcEfY &openid.claimed_id=https%3A%2F%2Fwww.google.com%2Faccounts%2Fo8%2Fid%3Fid%3DAItOawkIYyIzr6aa3CtLAlL4ESBi-2ytKUGcEfY &openid.ns.ext1=http%3A%2F%2Fopenid.net%2Fsrv%2Fax%2F1.0 &openid.ext1.mode=fetch_response &openid.ext1.type.guid=http%3A%2F%2Fschemas.openid.net%2Fax%2Fapi%2Fuser_id &openid.ext1.value.guid=(グローバルユニークなユーザー識別子) &openid.ext1.type.email=http%3A%2F%2Faxschema.org%2Fcontact%2Femail &openid.ext1.value.email=(メアド)
はい、同じ値が返ってきました。あ、いや、ここでは隠してるのでわかんないですが、同じ値が返ってきます。
ちなみに、この文字列を"https://www.google.com/profiles/"の後ろにつけると、プロフィールURLにリダイレクトします。
あ、Yahoo! JAPANのOpenIDみたいですねっ!
まとめ
- AXのRequestに"http://schemas.openid.net/ax/api/user_id"というパラメータを追加するとできそう
- ちなみに、他のAXパラメータと組み合わせないと値が来ないっぽい(詳細不明)
- Realmを変えてももちろん返る値は固定
- "https://www.google.com/profiles/"の後ろにつけると、プロフィールURLにリダイレクトするURLになる
これで複数RP間の名寄せ可能です。
今後、このパラメータがどうやって使われるのかはもちろん私にはわかりませんが、GoogleのOpenIDとつなぐサービスを構築する機会があるかたはこの仕様を覚えておいてもらえれば役に立つかもしれません。
試してみてください。
ではまた!