PHP OpenID Libraryこと始め

MixiOpenIDを使ってログイン認証するために仕様とか(MixiはOpenID 2.0)見てみた。
仕様書(英語)と、@ITの記事が参考になります。

1系と2系で用語が違うので混乱したよ・・・

ざっと流れを見ると、

  • User-Supplied Identifier(mixi.jpとか)をユーザーがRPに送信
  • User-Supplied Identifierを元にRPはHTTP接続(リダイレクト先があればどんどん追いかける)してOP Endpoint URLを決定(ディスカバリーというらしい)
  • OP Endpoint URLに認証要求のリクエストを送る(パラメータ付けてリダイレクト)
  • ユーザーはOPにログイン
  • OPからRPに認証情報付きでリダイレクト
  • RPで認証情報が正しいかチェック
    • openid.return_toの値が現在のリクエストのURLとマッチするか
    • レスポンスの中にClaimed Identifierがあるか
    • ディスカバリーで得た情報と照合
    • 同じopenid.response_nonceを2回以上受け取ってはいないか
    • 共通暗号鍵の照合
  • 認証OK!


作りたいのはRPなので、OPについてはあまり細かいところは見ずにフローを確認しただけ。
仕様ではないですが、アソシエーションの実行回数は単位時間で制限があるそうなので、どうキャッシュするか考えよう。


で、それをPHPでやる場合「PHP OpenID Library」を使うと簡単にできるみたい。
ググるとめちゃヒットするので、一番使われているライブラリっぽい。

試してみる際は、こちらのブログがとても参考になります。
mixi OpenIDのサンプルコードをPHP OpenID Libraryを使って動かしてみた
CurlとOpenSSLがない環境だとアウトですね。レンタルサーバーでやる場合は要確認。


ただ、いくつか自分の環境(Mac)だと詰まった点が。

証明書を書き出すとき、「証明書の階層」で「mixi.jp」を選択してから書き出す

これをやらないと書き出す項目が足りなくて、Curlでこんな感じのエラーが出ます

CURL error (60): SSL certificate problem, verify that the CA cert is OK. Details
:\nerror:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

ファイル名を「mixi.crt」とかで書き出した証明書の中身を見て、3つ項目が書き出されていれば成功です。


最後にもう1つ。
上の状態でPHP Open Libraryのサンプルを実行すると、Mixiの認証画面で認証して元の画面に遷移できるのですが、

OpenID authentication failed: No OpenID information found at https://id.mixi.jp/

というエラーが表示されます。

ということで、「https://id.mixi.jp/」の証明書も書き出して、中身を先ほど書き出したmixi.crtの末尾に追加します。

これで自分の環境ではエラーが出ず認証が上手くいきました。
OPへのリダイレクトURLがすごい長くなるので、現状の携帯サイトではちょっと使えないな。。。