こんばんは、ritouです。
PHPの話です。
この記事見てて思い出したのですが、
mixiへの認証を行ってくれる「OmniAuth-mixi」を公開しました - mixi engineer blog
OpauthっていうOmniAuthのPHP版みたいなのがあって、【実験的に】mixiとYahoo! JAPANのYConnect用のstrategyを作ったりしたことを残しておきます。
Opauthとは
Inspired by OmniAuth for Ruby, Opauth provides a standardized method for PHP applications to interface with authentication providers.
Opauth – Multi-provider authentication framework for PHP
Opauth as a framework provides a set of API that allows developers to create strategies that work in a predictable manner across PHP frameworks and applications.
inspired by OmniAuth for Ruby.
mixi用のstrategy : opauth-mixi
GitHub - ritou/opauth-mixi: Mixi strategy for Opauth
既にいろんなstrategyが出ていましたので、OAuth 2.0を使っているGoogle/Github/Facebookあたりの内容を流用して微調整したら動きました。
認証のライブラリなので、次の3つの機能を実装すればいい感じです。
- request() : Authorization Endpointへのリクエストを作る
- oauth2callback() : Clientのredirect_uriの処理
- userinfo() : People APIからプロフィール情報とって変数に格納
イメージをつかむためには動いてるのを見るのが早いですね。
READMEどおり導入できるので説明は省略します。
下記URLにアクセスするとmixi Graph APIのAuthorization Endpointにリダイレクトします。
http://www8322u.sakura.ne.jp/opauth/example/mixi
(Client登録時のredirect_uriはhttp://www8322u.sakura.ne.jp/opauth/example/mixi/oauth2callbackで登録しておきました。)
戻ってくるとPeople APIの一部を利用したユーザー情報が取れてますよっと。
Opauthのセッション周りの実装があやしいというか、あんまり気にされていない気がするのでstateパラメータのセット/チェックをしていません。$_SESSION使えばPlainなPHPでは動くんだろうけどフレームワークに対応できなそう。とはいえ、こうやって紹介するのであればCSRF対策が不十分って言われるより$_SESSION使うほうがいいのかな。OAuth 1.0でRequest Tokenとかを保存しないといけないTwitterのStrategyとかはつかってる気がします。悩みますね。
Yahoo! JAPANのYconnect用のstrategy : opauth-yahoojp
https://github.com/ritou/opauth-yahoojp
これは同じようにYConnect用に作ったもの。
ひたすらreplaceすれば動くかと思ったら1点問題発生。
Token EndpointでAuthorization HeaderにClient ID/SecretをBasic認証の形式でセットするところがあります。OpauthでもHeaderをサポートしてそうだったのでこんな感じで書きました。
$options = array( 'http' => array( 'header' => "Content-type: application/x-www-form-urlencoded\r\n". "Authorization: Basic ".base64_encode($this->strategy['client_id'] . ':' . $this->strategy['client_secret']) ) );
でも、動かしたら何も起こらない。
なぜかと思い、Opauth側の実装見たらこうなってました。
$stream = array('http' => array( 'method' => 'POST', 'header' => "Content-type: application/x-www-form-urlencoded", 'content' => $query )); $stream = array_merge($options, $stream);
これ、$options['http']に値入ってても$stream['http']の値で上書かれてるのでは。。。
他のStrategyで使ってないのかなと思って確認したけど、使ってないっぽいので、直してPull Req→無視←イマココ。 (2013/1/10追記)開発者から反応があって、 array_merge_recursive でいけたのでそれで直してもらいました。
mixiのStrategy作ったときは勝手に見つけてOpauthのページに掲載してくれたのに!
(2013/1/10追記)Strategyのところに追記されました。 https://github.com/uzyn/opauth
- $stream = array_merge($options, $stream);
-
+ if(isset($options['http'])){
+ $stream['http'] = array_merge($stream['http'], $options['http']);
+ }
とりあえず、yconnect版を使いたければこちらからどうぞ。
GitHub - ritou/opauth: Multi-provider authentication framework for PHP
あ、他の人のいじるのにmasterブランチにコミットしてた。まぁいっか。。。
ここから動作が確認できます。
http://www8322u.sakura.ne.jp/opauth/example/yahoojp
たくさんデータくださいしてるので気をつけてください。
気になるので時間があったらやるかもなこと
OpenID Connect用 Strategy
OAuth 2.0用のやつにDiscoveryとかDynamic Client Registrationあたりの機能を入れればいけるかなと。
毎回Registrationするとうざそうなので考えなければならないことはありそうです。
Session周りの拡張
stateパラメータをサポートしていない理由がこちらです。TwitterとかのStrategyで平気で$_SESSIONとか使ってるんですが、フレームワークによってSessionの扱いって別だと思うのです。なので、その違いを吸収するようなクラスをOpauthで持ってないとダメな気がしているのですが、まだCakePHPやCodeIgniterで試してないのでなんとも言えません。誰か試した人いますかね?
わりとテスト少ない
。。。
ところで、Opauthってどれだけ使われてんのかな。