このページは、authenticationの和訳です。実装面や全体の流れは「Open Graphに触れる 2:ユーザ認証と権限の認可」もどうぞ。


Facebook Platformは、ユーザ認証と権限の認可にはOAuth 2.0 protocolを用います。ウェブサイト上、モバイル、デスクトップなどで扱えるように、多くの異なるOAuthのフローをサポートしています。このドキュメントでは、Facebook Platformが使っているそれら各フローの仕組みを解説します。ここでのサンプルには、サーバサイドにはPHP、クライアントサイドにはHTML/JavaScriptを用いています。これらのサンプルは明解なので、他の言語へ簡単に置き換えることができます。


目次:

User Login

Facebook Platformは、ユーザのログイン用に2つのOAuth2.0のフローを用意しています。server-side (仕様上でauthentication code flowと呼ばれている部分です) と、client-side(implicit flowと呼ばれます)です。サーバサイドのフローは、あなたのウェブサーバからGraph APIを使う必要のあるときならいつでも使えます。クライアントサイドのフローは、ブラウザ上でJavaScriptによって、もしくはモバイルやデスクトップのアプリから、Graph APIを用いるときに用います。


用いるフローに関わらず、FacebookのOAuth2.0の実装は3つのステップから成り立ちます。user authentication, app authorization, app authenticationです。user authenticationで、ユーザが誰であるのかを保証します。app authorizationは、ユーザがアプリに対してどの情報を提供するのか理解していることが保証されます。app authenticationは、ユーザが他の誰かにではなく、あなたのアプリに対して情報を提供することが保証されます。これらの手順が完了すると、アプリはuser access tokenを与えられ、ユーザの情報にアクセスしたりユーザの代理として行動できるようになります。

Server-side Flow

user authenticationとapp authorizationは、ユーザをOAuth Dialogへとリダイレクトするのと同じタイミングで同時に行われます。このダイアログを開くときには、Developer Appでアプリを作成した時に与えられたapp id(cliend_idパラメータ)と、完了後のリダイレクト先(redirect_uriパラメータ)を渡さなくてはなりません。redirect_uriはDeveloper AppのWeb siteタブで設定したSite URLのドメインと同じドメインでなくてはなりません。

https://www.facebook.com/dialog/oauth?
     client_id=YOUR_APP_ID&redirect_uri=YOUR_URL

ユーザがログイン済みだった場合、ユーザのブラウザ上に保持されているクッキーでログイン状態をチェックし、ユーザ認証します。ユーザが未ログインだった場合、ログインを促されます。


auth_login


ユーザ認証に成功すると、アプリに対して権限を認可するよう、OAuthダイアログがユーザに促します。


auth_authz


デフォルトで、ユーザはアプリに対してbasic informationへのアクセスを認可するように求められます。これらは公開されていたり、デフォルトでFacebook上で公開されている情報です。この基本情報以上の情報が必要な場合は、必要に応じたパーミッションを得る必要があります。これは、OAuth Dialogリクエストの際にカンマ区切りのパーミッションのリストをscopeパラメータに指定することで実現できます。以下のサンプルが、ユーザのemailとnews feedへのアクセスを求める方法を示しています。

https://www.facebook.com/dialog/oauth?
     client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&scope=email,read_stream

上記の結果、ログイン後に以下のようなダイアログが開きます。


auth_perms
パーミッションの一覧はpermissions reference.で見る事ができます。求めるパーミッションの数とそれらを承認するユーザ数には、強い反比例の関係があります。多くのパーミッションを求めるほどそれを承認するユーザ数は減ってしまいますので、本当に必要なものだけを選ぶようお勧めします。


ユーザがDon't Allowを押した場合、アプリは認可されません。OAuth DialogはHTTPステータスコード302でredirect_uriパラメータで指定されたURLへ、以下のようなエラー情報とともにリダイレクトされます。

http://YOUR_URL?error_reason=user_denied&
     error=access_denied&error_description=The+user+denied+your+request.

ユーザがAllowを押した場合、アプリに対して権限が認可されます。OAuth DialogはHTTPステータスコード302でredirect_uriパラメータに指定されたURLへ、以下のようなauthorization codeとともにリダイレクトされます。

http://YOUR_URL?code=A_CODE_GENERATED_BY_SERVER

このコードを用いることで、次のステップ(app authentication)へと進んでAPI利用に必要なaccess tokenを得ることができます。


アプリを認証するため、Graph APIの https://graph.facebook.com/oauth/access_tokenに対してauthorization codeとapp secretを送る必要があります。app secretは Developer Appで得ることができますが、誰かと共有したり、公開するコード上に書いてはいけません(そのような場合にはクライアントサイドのフローを使うべきです)。

https://graph.facebook.com/oauth/access_token?
     client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&
     client_secret=YOUR_APP_SECRET&code=THE_CODE_FROM_ABOVE

アプリが認証されてauthorization codeが正しいものと分かれば、authorizationサーバはaccess tokenを返します。


auth_token
access token(access_tokenパラメータ)の他に、そのトークンが無効となるまでの秒数(expiresパラメータ)が渡されます。トークンが無効になると、上記のプロセスをもう一度実行して新しいaccess_tokenを得る必要がありますが、すでにアプリを認可していれば、また同じことをするように促されることはありません。ずっと有効なaccess tokenが必要な場合(ユーザがアプリを使っていない時にユーザの代理として何かする時など)は、offline_accessパーミッションをリクエストすることができます。

アプリを認可するのに問題がある場合、authorizationサーバはHTTPステータスコード400で以下のようなエラーをレスポンスで返します。

{
"error": {
"type": "OAuthException",
"message": "Error validating verification code."
}
}
以下のPHPサンプルはサーバサイドのフローの例を示しています。
<?php 

$app_id = YOUR_APP_ID;
$app_secret = "YOUR_APP_SECRET";
$my_url = "YOUR_URL";

$code = $_REQUEST["code"];

if(empty($code)) {
$dialog_url = "http://www.facebook.com/dialog/oauth?client_id="
. $app_id . "&redirect_uri=" . urlencode($my_url);

echo("<script> top.location.href='" . $dialog_url . "'</script>");
}

$token_url = "https://graph.facebook.com/oauth/access_token?client_id="
. $app_id . "&redirect_uri=" . urlencode($my_url) . "&client_secret="
. $app_secret . "&code=" . $code;

$access_token = file_get_contents($token_url);

$graph_url = "https://graph.facebook.com/me?" . $access_token;

$user = json_decode(file_get_contents($graph_url));

echo("Hello " . $user->name);

?>

Client-side Flow

クライアントサイドのフローもOAuth Dialogでuser authenticationとapp authorizationを行います。唯一の違いは、response_type=tokenを指定しなくてはいけないことです。

https://www.facebook.com/dialog/oauth?
     client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&response_type=token

サーバサイドと同じく、scopeパラメータを指定することで追加のパーミッションをリクエストすることができます。

https://www.facebook.com/dialog/oauth?
     client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&scope=email,read_stream&
     response_type=token

ユーザ認証し、アプリの権限が認可されると、redirect_uriで指定したURLへリダイレクトされます。サーバサイドのフローのようにcodeパラメータでauthorization codeが渡されることはなく、URIフラグメント(#access_token)として渡されます。

http://YOUR_URL#access_token=166942940015970%7C2.sa0&expires_in=64090

URIフラグメントとしてaccess tokenが渡されるので、クライアントサイドのコード(ブラウザ上で実行されるJavaScriptなど)のみがトークンを受け取ることができます。app authenticationは、redirect_uriのドメインがDeveloper AppのSite URLに指定したドメインと同じものであるとチェックして行います。


以下のHTML/JavaScriptの例は、クライアントサイドのフローを示しています。

<html>
<head>
<title>Client Flow Example</title>
</head>
<body>
<script>

var appId = "YOUR_APP_ID";

if(window.location.hash.length == 0)
{
url = "https://www.facebook.com/dialog/oauth?client_id=" +
appId + "&redirect_uri=" + window.location +
"&response_type=token";
window.open(url);

} else {
accessToken = window.location.hash.substring(1);
graphUrl = "https://graph.facebook.com/me?" + accessToken +
"&callback=displayUser"

//use JSON-P to call the graph
var script = document.createElement("script");
script.src = graphUrl;
document.body.appendChild(script);
}

function displayUser(user) {
userName.innerText = user.name;
}
</script>
<p id="userName"></p>
</body>
</html>

Using the Access Token

有効なaccess tokenがあれば、Graph API(とLegacy REST API)のリクエストにaccess_tokenパラメータとして渡すことでGraph APIを利用することができます。

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

ユーザがパスワードを変更すると、access tokenは無効になります。また、ユーザがApp Dashboardからアプリの権限認可を取り消した場合、Graph APIはHTTPステータスコード400で以下のようなレスポンスを返します。

{
"error": {
"type": "OAuthException",
"message": "Error validating access token."
}
}
再度適切なフローを実行することで新しいaccess tokenを得ることができます。

App Deauthorization

ユーザがApp Dashboardからアプリを取り除いてしまったり、News Feedでアプリをブロックすると、アプリ側はDeveloper Appで指定する Deauthorize Callback URLから通知されます。アプリを取り除くとき、HTTP POSTリクエストでsigned_requestというパラメータが送られ、デコードすると削除したユーザのuser_idを含むJSONオブジェクトになります。このリクエストではユーザのaccess tokenは渡されず、また、この時点で該当ユーザのaccess tokenは全て無効になります。


App Login

User Loginだけでなく、Facebook PlatformはOAuth2.0 Credential flowを使ったApp Loginもサポートしています。App Loginは、アプリの管理者として様々な情報を得ることを可能にします。たとえば、insightsの統計情報へのリクエストを認可したりです。アプリ用のaccess tokenを要するGraph APIの利用に関しては、APIリファレンスに明記されています。


アプリ用のアクセストークンは、https://graph.facebook.com/oauth/access_tokenに対して、アプリidとアプリのsecret key、それからgrant_typeにclient_credentialsを指定したものを渡して得られます。アプリのIDとsecret keyは、 Developer Appでアプリを作成した時に生成されます。

https://graph.facebook.com/oauth/access_token?
     client_id=YOUR_APP_ID&client_secret=YOUR_APP_SECRET&
     grant_type=client_credentials

HTTP GETリクエストを上記URLへ送ると、ボディにaccess_tokenが入った状態でレスポンスが返されます。


app_token

Graph APIの特定の分野(例えばApp Insightsなど)へアクセスするには、このアクセストークンを用います。

https://graph.facebook.com/YOUR_APP_ID/insights?
     access_token=TOKEN_FROM_ABOVE


Page Login

Facebook Pageは、ユーザログインやアプリログインとは若干違うフローを用います。ページには一人もしくはそれ以上の管理者がいます。これら全部の管理者が管理を行えるようにするには、ユーザがmanage_pagesパーミッションを与える必要があります。
https://www.facebook.com/dialog/oauth?
     client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&scope=manage_pages&
     response_type=token

manage_pages
管理者がこのパーミッションを与えると、User Graph APIのaccount connectionにアクセスできるようになります。
https://graph.facebook.com/me/accounts?access_token=TOKEN_FROM_ABOVE

このconnectionは、該当ユーザが管理者となっている全ページの詳細と、それぞれのページのアクセストークンのリストを返します。


page_tokens

任意のページ用のアクセストークンを用いることで、ユーザの代理としてそのページの管理行動をとることができます。


App Types

Facebook Platformは、Websites, Apps on Facebook.com, Mobile,Desktop Appsなど異なる種類のアプリに対し、上記のように様々なOAuthフローを提供しています。

Websites

Website Getting Started Guide では、JavaScript SDK and Login Social Pluginを用いてwebサイトにユーザログインを追加する方法の概略を説明しています。

Apps on Facebook.com

Apps on Facebook.com Getting Started Guideでは、Facebook上のアプリでユーザログインを扱う方法を解説しています。

Mobile Apps

Mobile App Getting Started Guideでは、mobile SDKでOAuth Dialogを用いてモバイル端末でユーザログインを使う方法を紹介しています。

Desktop Apps

これらOAuth2.0の実装は、デスクトップアプリのサポートを含んでいません。しかし、あなたの作るデスクトップアプリにwebブラウザを組み込める(.NET, AIR, Cocoa などほとんどのデスクトップフレームワークはサポートしています)のなら、client-side flowを一部改変(redirect_uri)して使うことができます。デスクトップアプリに対してwebサーバをホストしてサイトURLを持たせる代わりに、http://www.facebook.com/connect/login_success.htmlというURLを提供しています。

  • webブラウザを組み込んでOAuth Dialog(https://www.facebook.com/dialog/oauth)を読み込み、client-side flow(response_type=tokenなど)を使います
https://www.facebook.com/dialog/oauth?
client_id=YOUR_APP_ID&
redirect_uri=http://www.facebook.com/connect/login_success.html
  • ユーザがアプリに対して権限を認可すると、ユーザはredirect_uriへとURIフラグメント中にアクセストークンを持ってリダイレクトされます。
http://www.facebook.com/connect/login_success.html#access_token=...
  • このリダイレクトを受け取ったらURIからアクセストークンを読みこみます


Security Considerations

Cross Site Request Forgery (CSRF)

Cross site request forgeryは、信頼されている(認証/認可した状態)ユーザが知らない間にwebサイト上で行動をとらされる攻撃です。これを防ぐため、stateパラメータでidentifierを渡し、それをレスポンスと一致するかチェックすべきです。Facebookユーザログインを実装する全てのアプリが、この方法を用いてCSRFに対応することを強く勧めます。