Facebook OAuth認証(認証ありで誕生日とEmailを取得)

FBアプリは何がアプリ何だと言えないほど無数のやり方があるので、アプリって何だといわれると困るのですが、その中でも位一番おもしろいGraph APIの練習をしてみます。Graph APIはFBユーザーの登録情報にユーザーがアクセスを許可した場合にその中身を取り出せるというものです。例えば友達のリストが取得できればリレーゲームのようなものを作成したり、誕生日とEmailアドレスを取得できれば、その誕生日の占い結果などを週刊で配送できるとか...そういうようなことです。ここでは誕生日と登録しているメールアドレスを取得します。

Facebook GraphでEmailと誕生日を取得する

何もしなくてもFBではすでにここまでの情報は得ることができます。しかし、Emailアドレスや誕生日などは個人情報なので本人の認証をえなければ他者は見ることができません。しかし、いちいち誕生日を入力させるだとかEmailアドレスを訊くだとか面倒臭い作業を省いて、当の本人がその情報を使ってもいいよという許可をすれば、FBアプリはその情報を取得することができます。
ユーザーは個人の情報を開示する項目とその範囲を選択することができます。勿論キャンセルすることもできます。許可した後にその変更も可能ですし、間違って許可した際にはその設定を取り消すこともできます。

アプリを作成する

1. アプリを作成する
取り急ぎアプリを作成します。アプリはここから作成します。認証もののアプリなので「Website with Facebook Login」でサイトURLを設定してください。この時、アプリの基本データのApp DomainsとアプリをFacebookに結合する方法を選択での「Website with Facebook Login」で設定するURLに整合性がないといけません。ドメインは基本ドメインを設置します。サイトのURLはサイトのトップページ辺りを記述しておくのが無難です。しかしドメインとサイトのURLはDomain -> サイトのURLという感じで常に設定したドメインを含んでいなくてはいけません。つまりドメインはサイトURLの十分条件で、サイトURLはドメインの必要条件でなくてはなりません。更に、実際にFB APPの仕掛けを置くWEBページは、指定したサイトURLの配下である必要があります。

2. 作成したアプリの情報を得る
アプリを作成すると2つの重要な情報を得ることができます。それが、

  • アプリID: $app_id = '173649622773521';
  • アプリのキー: $app_secret = "4ed0000000000032c297590000000000";

です。アプリのIDは、あなたがどのアプリを使っているのかをアイデンティファイするもので、外に出しても構いませんが、APPシークレットといわれるものは、いわゆるアプリのアクセスパスワードみたいなものなので外部に晒すのはセキュリティー的に問題があります。なので、App Secret:の方は人に教えたり晒したりしてはいけません。

3. アプリにアクセスする
実際にアクセスするコードは以下みたいな感じです。
<a href="https://www.facebook.com/dialog/oauth?client_id=173649622773521&redirect_uri=http://example.com/result.php&scope=email,user_birthday">Login</a>

FaceBook Graphの基本APIは、以下になります。
https://www.facebook.com/dialog/oauth
このAPIにアクセスすることでアプリを使ったOAuth認証が可能になります。APIは基本的にはアクセスすると何かが返ってくるものというだけで特に難しいことではありません。通常の関数と大した違いはないのです。
このアクセスの時に必要なものは、先のアプリのIDや諸々をアイデンティファイする情報です。それが?以下の引数になっています。スコープで設定するパラメーターはFacebook的に「パーミッション」と呼ばれていて(紛らわしい)詳しくはこちら(英語)に載っております。日本語訳ページはこちら。

App ID:[client_id=] 173649622773521
リダイレクト先:[redirect_uri=] redirect_uri=http://example.com/result.php
スコープ:[scope=] email,user_birthday

上記の情報をFBのOAuthアプリに送ってあげることで、FBの認証機能を通すことができます。まず、App IDであなたの指定したFBアプリにアクセスするように指示しています。そのアプリではすでにどのドメイン中で認証するのかを予め記述済です。認証機能を通して認証した場合・認証しない場合にリダイレクトするWEBページを指定します。認証後の行き先がなくては困るからです。最後に認証した後にアクセスする情報をコンマ区切りで記述します。(FB的にはパーミッションという呼びだ方をしています。要するにどの情報を許可するのかといったパラメーターを設定するのです。)この3つの設定を引数に与えてOAuthにアクセスすればよいわけです。

  • もし認証が通れば、リダイレクト先にcode付きで飛びます。
  • 認証がまだ終わっていない、これから、という場合は、認証ダイアログが表示されます。
  • もし認証に失敗したら、リダイレクト先にcodeなしで飛びます。

codeを取得するまでの流れは前回のこれになります。ただログインするだけです。ログイン後のURLのお知りに付いてくる文字列がcodeです。

アクセストークンを取得する

OAuth認証が成功すると、codeがURLの後ろにくっついてリダイレクトで指定したページに飛びます。しかしまだ認証が終わったわけではありません。やっとアプリの機能の入り口に来たのみです。
デバック:https://developers.facebook.com/tools/debug
アプリの入り口まで行くには以下のcodeが必要です。認証が完了するとURLの後ろにくっついて送信されます。
code=Afbasudh87q45gtgsFOAVuh18Efj7HGKHKG5_FsHrZLpcILC5ff3GOXhu1g1rKulzJuF_SDkertwm4S6fixCHnHKGertwewxtSyd7FmWzbdAqMXIyG2TkwBPm0B1ww0XKJHHGKshpf8sd8d8t76gsa7ezw3d6lERjnRFWGfKAQHj5UsGo5do-fC-hasdfafd1TS71#_=_

これはただの順番待ちのカードみたいなもので、特に認証やログインに関して特別な機能をもっていません。しかし持っていなければ入室はできません。このcodeはアクセストークン発行時に使います。
アプリを作成してそのアプリの認証機能を利用する時、最終的にアクセストークンなるものを取得しなくてはいけません。これは、IDとパスワード(App Secret:)を2つセットにしたものと、先程得たばかりのcodeと、認証完了後のリダイレクト先の4つの情報を与えることでアクセストークンの発行ができます。
4つの情報をURLクエリにくっつけて
https://graph.facebook.com/oauth/access_token
に送りつけます。実際のコードは以下のように非常に長ったらしいものになります。
https://graph.facebook.com/oauth/access_token?client_id=173649622773521&redirect_uri=http://example.com/result.php&client_secret=4ed0000000000032c297590000000000&code=Afbasudh87q45gtgsFOAVuh18Efj7HGKHKG5_FsHrZLpcILC5ff3GOXhu1g1rKulzJuF_SDkertwm4S6fixCHnHKGertwewxtSyd7FmWzbdAqMXIyG2TkwBPm0B1ww0XKJHHGKshpf8sd8d8t76gsa7ezw3d6lERjnRFWGfKAQHj5UsGo5do-fC-hasdfafd1TS71#_=_
アクセストークンが最終的な入室書類になります。アクセストークンとその他の情報が正常に行け入れられると、先程scopecで指定したメールアドレスと誕生日を返してくれます。

// アプリの認証情報
$app_id = '173649622773521';
$app_secret = "4ed0000000000032c297590000000000";
$redirect_url = 'http://example.com/result.php';
$code = $_REQUEST["code"];

//access_tokenへのアクセスURLを作成
$token_url = 'https://graph.facebook.com/oauth/access_token?'.
'client_id='.$app_id.'&'.
'redirect_uri='.$redirect_url.'&'.
'client_secret='.$app_secret.'&'.
'code='.$code;

$response = file_get_contents($token_url);
parse_str($response, $params);
$graph_url = "https://graph.facebook.com/me?access_token=" . $params['access_token'];
$user = new stdClass;
$obj_user = json_decode(file_get_contents($graph_url));

最終的にGraph APIで得た情報は、オブジェクトで返ってきます。配列じゃないところがツーっぽいです。最終的に$obj_userにGraph APIの情報がオブジェクトで入ってきます。出てくる情報はこのページの最下部に載せています。
取得したユーザー情報はオブジェクトの形で取得できるのですが、WPなどと同様にオブジェクトを扱うのに不便なテンプレートエンジンや、またPHPそのもので処理する際は配列の方が断然扱いやすいという場合があります。勿論オブジェクト操作に慣れている方は、ここから先は自分で適当に得た情報を加工して何かしらのアプリを作ることになります。
FBアプリを許可すればSampleからあなたのFB情報が表示されます。(ただ表示されるだけです。)

 

オブジェクトで取り出せるのは以下の値です。(私のIDです。)この情報を使って占いをやったり統計をとったりいろいろできるわけです。

object(stdClass)#2 (17) {
["id"]=>
string(15) "100001278784xxx" ※Facebook ID: http://www.facebook.com/oosamuuy
["name"]=>
string(14) "Osamu Yamakami" ※フルネーム
["first_name"]=>
string(5) "Osamu" ※名前
["last_name"]=>
string(8) "Yamakami" ※姓
["link"]=>
string(32) "http://www.facebook.com/oosamuuy" ※IDのリダイレクト先
["username"]=>
string(8) "oosamuuy" ※ユーザー名
["birthday"]=>
string(10) "01/01/1980" ※生年月日
["bio"]=>
string(135) "Webデザインとかプログラムとかやっております。
絵を描くのが好きです。
http://www.omnioo.com/omnioolab/" ※自己紹介・プロフィール
["work"]=>
array(1) {
[0]=>
object(stdClass)#3 (3) {
["employer"]=>
object(stdClass)#4 (2) {
["id"]=>
string(15) "126434757426761" ※仕事ID
["name"]=>
string(27) "XXX株式会社" ※仕事先
}
["description"]=>
string(21) "WEBの会社です。" ※仕事先詳細
["start_date"]=>
string(7) "0000-00" ※仕事をはじめた年月日
}
}
["education"]=>
array(3) {
[0]=>
object(stdClass)#5 (3) {
["school"]=>
object(stdClass)#6 (2) {
["id"]=>
string(15) "105989719440600" ※卒業した学校ID
["name"]=>
string(18) "xxx高等学校" ※卒業した学校名
}
["year"]=>
object(stdClass)#7 (2) {
["id"]=>
string(15) "131367623569918" ※卒業年のID
["name"]=>
string(4) "1990" ※卒業年
}
["type"]=>
string(11) "High School" ※卒業学校の種類
}
[1]=>
object(stdClass)#8 (3) {
["school"]=>
object(stdClass)#9 (2) {
["id"]=>
string(15) "108291595861101" ※卒業した学校ID
["name"]=>
string(24) "xxx University" ※卒業した学校名
}
["year"]=>
object(stdClass)#10 (2) {
["id"]=>
string(15) "135676686463386" ※卒業年のID
["name"]=>
string(4) "1994" ※卒業年
}
["type"]=>
string(7) "College" ※卒業学校の種類
}
[2]=>
object(stdClass)#11 (2) {
["school"]=>
object(stdClass)#12 (2) {
["id"]=>
string(15) "214095831991952" ※卒業年のID
["name"]=>
string(18) "XX学園" ※卒業した学校名
}
["type"]=>
string(7) "College" ※卒業学校の種類
}
}
["gender"]=>
string(4) "male" ※性別
["email"]=>
string(18) "user@example.com" ※Email
["timezone"]=>
int(9)
["locale"]=>
string(5) "ja_JP" ※国
["languages"]=>
array(3) {
[0]=>
object(stdClass)#13 (2) {
["id"]=>
string(15) "105673612800327" *使用言語ID
["name"]=>
string(6) "German" *使用言語
}
[1]=>
object(stdClass)#14 (2) {
["id"]=>
string(15) "106059522759137" *使用言語ID
["name"]=>
string(7) "English" *使用言語
}
[2]=>
object(stdClass)#15 (2) {
["id"]=>
string(15) "109549852396760" *使用言語ID
["name"]=>
string(8) "Japanese" *使用言語
}
}
["verified"]=>
bool(true)
["updated_time"]=>
string(24) "2012-11-07T11:16:07+0000" *最終アップデート
}