前回の「Open Graphに触れる:基本」では、Open Graphが何であるか、そしてOpen Graphにアクセスする手段としてのGraph APIについて紹介しました。今回は、ユーザ認証(authenticate)と、ユーザから権限の認可(authorize)を受ける手順を紹介します。この手順を完了してアクセストークンを取得することにより、ユーザのウォールやグループに投稿したり、イベントを作成・管理したり、Facebookページを管理したりするなど、ユーザに代わってOpen Graph上のデータを読み書きできるようになります。
アプリケーションの登録
ユーザ認証したり権限の認可を受けるには、Facebook Platformでアプリケーションを登録しなくてはなりません。ここで作成されるアプリケーションIDを用いて認証・認可を行うことになります。まず、アプリ一覧ページへ行きます。初めてアプリを作成する場合、ここは以下のキャプチャのように空になっているので、「新しいアプリを作成」をクリックします。
アプリの名称やネームスペースを入力するフォームがポップアップしますので、App Nameにアプリ名を入力します。App Nameは必須ですが、App Namespaceは任意ですので、とりあえずは空のまま「続行」してください。後から設定画面で変更できます。
画像認証を求められますので、表示される文字列を入力して「続行」します。読みにくい場合は「別の文字を表示」で文字列を変更します。
ここまでの過程で、まだFacebook Platform開発者登録が済んでいない場合は、電話番号やクレジットカードを用いての本人確認を求められますので、手順に従って登録します。
それが済むと、作成されたアプリの設定画面へと遷移します。
このページでまず大事なのは、以下のキャプチャの通り、Sandbox Modeを「有効」にすることです。これにより、アプリの開発関係者のみがアプリを利用できる状態となりますので、開発中はずっと「有効」にしておきます。また、「Facebookでログインするウェブサイト」に、今回利用するウェブサイトのURLを入力しておきます。認証完了時にFacebook側からアプリのウェブページへリダイレクトされますが、そのリダイレクト先のドメインと、ここで入力する「サイトURL」のドメインは一致していなくてはなりません。
ユーザ認証と権限の認可
Facebookは認証と認可の手段としてOAuth 2.0を採用していて、ドキュメント中では、完了までのフローを以下の3つのステップで紹介しています。これら3つのステップに対し、OAuth 2.0が定めるフローの各ステップ(A~E)の対応を書いておきますので、それぞれのステップの詳細についてはOAuth 2.0仕様の4.1. Authorization Code Grantや、FacebookドキュメントのAuthentication和訳を参照してください。- User Authentication(ユーザ認証)
- Facebookのログイン状態をチェックし、未ログイン状態であればユーザにログインを促します。ここで、ユーザが誰であるのかが保証されます。
4.1. Authorization Code Grantの(A) - App Authorization(権限の認可)
- アプリが要求する権限のうち、全部、もしくはどれを許可するのかをユーザに確認します。ここで、アプリに対してどの権限を与えるのか理解していることが保証されます。
4.1. Authorization Code Grantの(B)と(C) - App Authentication(アプリ認証)
- 正しいアプリに対して権限を与えていることが保証されます。
4.1. Authorization Code Grantの(D)と(E)
実装
上記ステップのうち、ユーザ認証と権限の認可についてはAuthダイアログと呼ばれるダイアログページが担ってくれます。そのため、適切なクエリパラメータを付けてダイアログページにユーザをリダイレクトすれば、最後のアプリ認証のステップ以外は完了することになります。Authダイアログ
ユーザをリダイレクトするAuthダイアログのURLは以下のような形式になります。https://facebook.com/dialog/oauth/?redirect_uri=CALLBACK_URL&client_id=APP_ID&state=ANTI_CSRF_STRここで渡すそれぞれのパラメータは以下の通りです。
redirect_uri | 認証完了時にユーザが遷移してくるページのURLを、URLエンコードしたもの |
client_id | アプリ設定画面のApp IDの項目に出ている数値 |
state(オプション) | CSRF対策の為に用いられる文字列。完了時にこの値が返されるので、アプリ側でもこの値は保持しておき、同じ値が返されているかを比較します。 |
scope(オプション) | 基本データへのアクセス権限以外にも権限が必要な場合に指定するパラメータ。詳細は後述します。 |
サンプルは以下の通りです。
https://facebook.com/dialog/oauth/?redirect_uri=https%3A%2F%2Fsample.com%2Fauth_callback&client_id=1234567890&state=vlXgu64BQGFSQrY0ZcJBZASMvYvTHu9GQ0YM9rjPSso上記URLへとユーザが遷移すると、Facebook未ログインであればログインを促され、ユーザが誰であるかが保証された上で以下のようなダイアログが表示されます。
右にある「このアプリが受け取る情報」の項目を見ると、ユーザの基本データに関するアクセス権限を与えられることが分かります。通常はscopeパラメータで各権限を要求する必要がありますが、基本データのみはデフォルトで許可されます。ユーザが「アプリへ移動」を選択すると、ユーザは基本データへのアクセス権限を許可したこととなり、redirect_uriに指定したwebページへとリダイレクトされます。ここまでで、上記3ステップのうちユーザ認証と権限の認可までが完了しました。
アクセストークンの取得
ユーザが権限を認可し、redirect_uriに指定したURLへと遷移すると、以下のようにcodeパラメータも一緒に渡されます。https://sample.com/auth_callback?code=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX#_=_アクセストークンを取得するには、アプリ認証のため、このcodeの他にもapp ID(client_id)とApp secret(client_secret)が必要となります。いずれもアプリ設定画面の上部に書かれているので確かめてください。これら3つの値を使って、サーバサイドで以下のURLにアクセスします。
https://graph.facebook.com/oauth/access_token?redirect_uri=https%3A%2F%2Fsample.com%2Fauth_callback&client_secret=XXXXXXXX&client_id=1234567890&code=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
この段階で、client_id,client_secret,codeを基に、適切なアプリがアクセストークンをリクエストしていることが保証され、以下のようにaccess_tokenとexpiresが返されます。
access_token=AAAXXXXXXXXXXXXX&expires=5183951この際、redirect_uriにはダイアログ表示の際に使ったものと同じURLを指定します。この値が違った場合、「OAuthException:Invalid redirect_uri: 指定されたURLは、アプリケーションの設定で許可されていません」というエラーが返されますので気をつけてください。
また、expiresの値はアクセストークンが切れるまでの秒数を示しています。通常であれば60日(5184000秒)に近い数値が返されるはずです。
ユーザ情報の取得
ここまでで、ユーザから権限認可を受け、アクセストークンを受け取る所までは完了しました。しかし、OAuthは認証(authenticate:誰が誰であるかの保証)の手段ではなく認可(authorization)の手段であるため、この段階ではユーザIDなどの情報は渡されず、認可された権限を行使する為のトークンのみ渡されています。こういった場合には、Open GraphオブジェクトIDの代わりに"me"というエイリアスを利用します。これはユーザのアクセストークンと組み合わせた場合に有効で、オブジェクトIDの代わりに"me"を使うことで、アクセストークンの持ち主の情報へアクセスできます。Authダイアログの段階でFacebook側でのユーザ認証が完了し、そのユーザ用のアクセストークンが発行されているため、このアクセストークンを使ってユーザ自身の情報を取得すれば、アプリ側でもユーザの身元を保証できるというわけです。
そのため、Facebookでログインする機能を実装する場合は、上記手順の最後に以下のエンドポイントにアクセスしてユーザID等を取得するのが一般的です。
https://graph.facebook.com/me?access_token=AAAXXXXXXXXXXXXX
パーミッション
Facebookアプリを作る上で、ユーザのメールアドレスやウォール投稿内容など、基本情報以上の情報が欲しい場合があります。また、ユーザに代わってウォールに書き込みしたりイベント作成するなどの権限が欲しい場合も出てきます。そういった場合は、Authダイアログを開く際のscopeパラメータに、パーミッションと呼ばれる物を足してあげます。様々な権限にはそれに対応するパーミッションが定められていて、それをscopeパラメータでリクエストし、ユーザに許可してもらうことで様々な情報の読み書きが可能となります。例えば、emailというパーミッションを許可されればユーザのメールアドレスにアクセスできるようになり、read_mailboxというパーミッションを許可されればユーザの受信箱の中身を見ることができるようになります。以下のURLのように、カンマ区切りにしたパーミッション一覧をscopeパラメータに指定すれば大丈夫です。
https://facebook.com/dialog/oauth/?scope=email,read_mailbox,publish_actions&redirect_uri=https%3A%2F%2Fsample.com%2Fauth_callback&client_id=1234567890&state=Foo
ベストプラクティス
パーミッションを確かめる
パーミッションを要求した上でアクセストークンを取得できたとしても、リクエストしたパーミッション全てが許可されるわけではないことに気をつけてください。認証と認可の3つのステップの中で紹介した通り、ユーザはどの権限を与え、どれを拒否するか選択することができます。(詳細は「Facebook Night vol.7 発表内容まとめ 2:認証ダイアログの構成」を参照してください。)そのため、ユーザ情報を取得する際に、どのパーミッションが許可されたのかも確認することをお勧めします。以下のエンドポイントへのリクエストで、ユーザが許可したパーミッション一覧を取得できます。https://graph.facebook.com/me/permissions?access_token=ACCESS_TOKEN返り値は以下の通りとなります。
{ "data": [ { // key: パーミッション名, value: 1 "installed": 1, // アプリがインストール済(認証済み) "read_stream": 1, "user_birthday": 1, "user_religion_politics": 1, "user_relationships": 1,リクエストしたパーミッションのうち、どれが実際に許可されたのかを確認し、与えられた権限の範囲内でGraph APIを利用することとなります。現状では、ウォールへの投稿権限を拒否した上で利用開始したアプリでも、「ウォールに投稿する」オプションがチェックボックスで表示されることがあります。が、理想としてはどのパーミッションが許可されているかを必ず確認し、ウォールへの投稿権限が与えられていないのならば「ウォールに投稿する」オプションを非表示にするなどの配慮をすべきです。詳しくは「Facebook Night vol.7 発表内容まとめ 3:Batch RequestとReal-time Update API」を参照してください。
}
]
}
また、パーミッションの解説や一覧に着いては、Permissions和訳をご覧ください。
必要最低限のパーミッションのみ要求する
最善の機能を提供するには、ユーザから色々なパーミッションを得る必要が出てきます。しかし、最初のログイン段階でそれらを全て要求するのは、ユーザを警戒させ、離脱させてしまう原因になり得ます。こういった場合の対応については「Facebook Night vol.7 発表内容まとめ 2:認証ダイアログの構成」で以下のように紹介している通りです。もう一点大事なことは、必要なときに必要なパーミッションのみ要求することだと思います。アプリのインストール時には全ユーザに共通して必要となる最低限のパーミッションのみ要求し、あとは設定画面を設けておいて、On / Offの切り替え時に適宜要求するなどです。Kloutは 最初のログイン時はフィード読み込みなどのパーミッションしか要求せず、設定画面でFacebook共有をOnにするときに初めて投稿系パーミッションを 要求します。自分の影響度という繊細な部分を扱うサービスなので、最初から投稿系パーミッションを要求されると、自分の影響度が勝手に投稿されると感じて ためらうユーザもいるでしょうから、そのようなユーザの不安を避ける上でも参考になる実装例だと思います。
On / Offを切り替える際、ユーザがすでに該当するパーミッションを許可しているか否かを把握し、必要に応じてパーミッションを要求する必要がありますが、それに関しては3番目のエントリで紹介します。
(※ あとから追加でパーミッションを要求する場合は、追加で要求するパーミッションのみscopeに指定して認証ダイアログに飛ばせば大丈夫です。他のパー ミッションをscopeに指定しなかったからといって、既に許可されたパーミッションが消されてしまうことはありません。)