Facebookが採用してるOAuth2.0の仕様を調べてみた

Facebook流行って?ますね。
あまり使っていないですけど。
で、Facebookと言えば、いち早くOAuth2.0を採用していたりします。
そんなわけで、Facebookの採用している仕様を調べてみました。
乗ってるものには乗っていけの精神です。

Facebookの仕様は
Authentication - Facebook developers
OAuth 2.0はこちら
draft-ietf-oauth-v2-10 - The OAuth 2.0 Authorization Framework

Flow

Facebookはweb applicationを対象にしたFlow以外に

  • JavaScript-based authentication
  • Desktop application authentication
  • Mobile Web authentication
  • Canvas Applications (beta)

の4つのタイプをサポートしているようです。

今回はweb application flowのみ調べてみました。

Authorization

authZ endpointは
https://graph.facebook.com/oauth/authorize
パラメータは

parameter required?
client_id required
redirect_uri required
scope option
display option

となっています。
displayはFacebook独自のパラメータです。

URIを作成すると、

https://graph.facebook.com/oauth/authorize?client_id=...&redirect_uri=http://www.exaple.com/oauth_redirect

こんな感じになります。

scope

デフォルトでもいろいろとリソースは取得できますが、scopeパラメータを追加することで取得できるリソースが拡張されます。
scopeには追加したいpermissionを,区切りで指定します。
(OAuth2.0ではspace-delimitedとなっているのでそっちも試してみたところ一応出来ました。)
scopeの詳しい仕様はPermissions Reference - Facebook developersに載ってます。

display

displayパラメータを指定することで認可ページの表示方法を指定できるようです。

# page - Display a full-page authorization screen (the default)
# popup - Display a compact dialog optimized for web popup windows
# wap - Display a WAP / mobile-optimized version of the dialog
# touch - Display an iPhone/Android/smartphone-optimized version of the dialog

こんな感じ。
display parameterはOAuth2.0には無い仕様です。

access tokenの取得

認可ページでユーザーが許可をするとauthZ endpointで指定したredirect_uriにユーザーは遷移します。
redirectされるときにcodeパラメータがクエリパラメータとして付加されているので、このcodeと交換でaccess tokenを取得します。

token endpointは
https://graph.facebook.com/oauth/access_token
パラメータは

parameter required?
client_id required
client_secret required
redirect_uri required
code required

となっています。

URIを作成すると、

https://graph.facebook.com/oauth/access_token?client_id=...&redirect_uri=http://www.example.com/oauth_redirect&client_secret=...&code=...

という感じになります。

OAuth 2.0の仕様としてはaccess token取得時のmethodはPOSTだけど、FacebookはGETのようです。
また、この時のResponseもOAuth 2.0の仕様ではjsonですが、

access_token=...&expires=...

という感じの文字列が返ってきました。

APIリクエスト

こんな感じで

https://graph.facebook.com/me?access_token=...

OKです。簡単!

その他

authZ endpointでユーザーが拒否した場合はredirect_uriで指定したuriにユーザーを遷移させますが、このときerror_reasonというparameterを付加してくれます。error_reasonというパラメータも特にOAuth2.0の仕様で規定されているものではないです。

また、Facebookはrefresh tokenの発行はしませんが、offline_access permissionがないと access tokenに有効期限が設定されるそうです。で、scopeにoffline_access permissionを追加しておくと有効期限がなくなるとのこと。ちなみに、ユーザーがpasswordを変更するとoffline_access permissionがあっても無効になります。

あと、やってて気づいたのですが、codeとaccess tokenの交換は何度でもできます。取得できるaccess tokenの値は同一ですが、offline_access permissionを付加しない場合、expiresの値がだんだん減っていきます。

まとめ

今回はここまで。
access tokenを取得する部分が案外最新のOAuth2.0の仕様と異なっていました。レスポンスがjsonじゃなかったり、リクエストもパラメータをクエリパラメータとして付加するようになっていたり。

OAuth 2.0のアップデートを追いかけているようなので、完全に最新の仕様と同一にはならないということなんでしょうか。

他にもいろいろ気になるところがあるけど、それはまた今度。