今回は、ユーザさんの新規会員登録をFacebookログインから行うサンプルです。新規登録画面でFacebookから取得できるユーザ情報ははじめから補完していく流れをみていきます。OAuth2という認証方式が使うので、その仕組みを 「SNS連携やってみた!OAuth2の処理の流れまとめてみる」にまとめました。また、アクセストークン取得までは、「FacebookとSNS連携!SDKを使わずにOAuth2でアクセストークン取得する/PHP」でまとめました。
PHPはSDKが準備されているのですが、今回はSDKを使わずにPHPでユーザ情報を取得する処理をまとめてみます。
処理の流れ
例として次のような流れを考えてみます。
- クライアント(自社サイト)に「Facebookで新規会員登録ボタン」を配置します。
- ユーザさんはそのボタンをクリックします。そしてしばらくはFacebookとのやり取りが続きます
- Facebookはユーザさんとのやり取りの結果をクライアントに返します。ユーザさんがクライアントにアカウント操作する許可を出せば、アクセストークンを取得する処理まで進めます。
ここまでは、「FacebookとSNS連携!SDKを使わずにOAuth2でアクセストークン取得する/PHP」でまとめました。
- クライアントはFacebookにユーザのプロフィール(ユーザ)情報をくださいとお願いします。
- Facebookはユーザさんが許可した範囲内でプロフィール(ユーザ)情報をクライアントに渡します。
- クライアントは新規会員登録画面をユーザに表示します。そのとき、名前などFacebookから取得できた情報ははじめから入力された状態(入力補完)しておきます。
- ユーザは残りの項目を入力し新規会員登録を行います。
今回は新規会員登録の補完を例にしましたが、FacebookのユーザIDと自社サイトの会員IDだけを最初に紐付けてログインさせればFacebookログインしただけで会員登録終わりです。後は、自社サイトのマイページに入ってサービスに必要な情報の残りをいつでも入力してくださいの遷移もありますね。
ユーザ情報を取得する Graph API User
「FacebookとSNS連携!SDKを使わずにOAuth2でアクセストークン取得する/PHP」でアクセストークンを取得しました。このアクセストークンを使って許可された権限の範囲でユーザ情報を取得します。
APIのリンク先は以下になります。
https://graph.facebook.com/{user-id}
【参考】Facebook developer > Graph API User
{user-id} には取得したいユーザのIDを指定します。自社サイト運営者のユーザIDを指定すれば、自分で投稿した写真や「いいね」数など取得してサイトに反映できますね。
では、ログインした人のユーザをどのように指定すればいいかというと以下のように指定します。
https://graph.facebook.com/me
【参考】Facebook developer > Using the Graph API
{user-id} に「me」を指定すればログインしているユーザの情報が取得できます。
パラメータとしてアクセストークンを指定します。
https://graph.facebook.com/me?access_token=hogehoge
これでFacebookからログインしているユーザさんの情報が取得できます。
ちなみにアクセストークンを指定しない場合、以下のようなエラーを返してきました。
"error": { "message": "An access token is required to request this resource.", "type": "OAuthException", "code": 104 }
サンプルコード
完成サンプル:GitHub
今回の処理の流れは、sample02.phpにまとめました。アクセストークンを使ってユーザ情報を取得しレスポンスを表示するだけのサンプルです。
fb_api_graph_user.php : ParamsGraphUserクラス
class ParamsGraphUser { const VALID_ACCESS_TOKEN = "Param graph/user valid access_token."; const VALID_LOCALE = "Param graph/user valid locale."; private $accessToken = ""; private $locale = "ja_JP"; public function getAccessToken(){ return $this->accessToken; } public function setAccessToken($val = ""){ if(!is_string($val)){ throw new Exception(self::VALID_ACCESS_TOKEN); } $this->accessToken = $val; } public function getLocale(){ return $this->locale; } public function setLocale($val = ""){ if(!is_string($val)){ throw new Exception(self::VALID_LOCALE); } $this->locale = $val; } }
Graph API User のパラメータを設定するクラスです。基本はアクセストークンがあればユーザ情報が取得できるのですが、日本語を表示したい場合は localeも設定しないと日本語情報が取得できませんでした。
object(stdClass)#6 (12) { ["id"]=> string(15) "hogehoge" ["birthday"]=> string(10) "dd/mm/yyyy" ["email"]=> string(25) "hoge@yahoo.co.jp" ["first_name"]=> string(6) "Taro" ["gender"]=> string(6) "male" ["last_name"]=> string(6) "Yamada" ["link"]=> string(60) "https://www.facebook.com/app_scoped_user_id/hogehoge/" ["locale"]=> string(5) "ja_JP" ["name"]=> string(13) "Taro Yamada" ["timezone"]=> int(9) ["updated_time"]=> string(24) "2015-07-04T04:26:06+0000" ["verified"]=> bool(true) }
localeに「ja_JP」をパラメータとして渡すことで日本語表示できます。
object(stdClass)#6 (12) { ["id"]=> string(15) "hogehoge" ["birthday"]=> string(10) "dd/mm/yyyy" ["email"]=> string(25) "hoge@yahoo.co.jp" ["first_name"]=> string(6) "太郎" ["gender"]=> string(6) "男性" ["last_name"]=> string(6) "山田" ["link"]=> string(60) "https://www.facebook.com/app_scoped_user_id/hogehoge/" ["locale"]=> string(5) "ja_JP" ["name"]=> string(13) "山田 太郎" ["timezone"]=> int(9) ["updated_time"]=> string(24) "2015-07-04T04:26:06+0000" ["verified"]=> bool(true) }
fb_api_graph_user.php : getUserクラス
class ApiGraphUser { const API_URI = "https://graph.facebook.com"; const AGU_ERROR_PARAMS_EMPTY = "Api graph/user empty params."; const AGU_ERROR_VALID_USER = "Api graph/user valid user."; const AGU_REQUIRED_ACCESS_TOKEN = "Api graph/user required access_token."; public static function getMe(ParamsGraphUser $params = null){ return self::getUser($params , 'me'); } public static function getUser(ParamsGraphUser $params = null , $user = null){ $apiParams = array(); if(is_null($params)){ throw new Exception(self::AGU_ERROR_PARAMS_EMPTY); }elseif(is_null($user) || !(is_string($user) || is_int($user))){ throw new Exception(self::AGU_ERROR_VALID_USER); }elseif("" === ($apiParams['access_token'] = $params->getAccessToken())){ throw new Exception(self::AGU_REQUIRED_ACCESS_TOKEN); } $apiParams['locale'] = $params->getLocale(); $uri = self::API_URI . "/{$user}?" . http_build_query($apiParams); $opts = array( 'http' => array( 'ignore_errors' => true ) ); $context = stream_context_create( $opts ); $response = file_get_contents($uri , false, $context ); return json_decode($response); } }
Graph API User のロジッククラスです。単に必要パラメータを受けて、URLを作りFacebookからレスポンスを受け取ってます。
APIからの取得にfile_get_contents関数を使いました。
$opts = array( 'http' => array( 'ignore_errors' => true ) );
$context = stream_context_create( $opts );
$response = file_get_contents($uri , false, $context );
オプションで、ignore_errorsをtrueにしています。そうしないとFacebook側がエラーがあるとHTTPステータス400とか返してくるのでPHPがWarningが出ました。こうしておくとWarningも出ずレスポンスのエラーパラメータから問題なく処理できました。
sample02.php
<?php /** * Facebook API を使ってアクセストークンを取得するサンプル * * ※ SDKは使わずにOAuth2を利用したサンプル */ /** 各環境にあわせて変更してくさい. START */ define('APP_ID', 'hoehoge'); define('APP_SECRET', 'hogesecret'); define('REDIRECT_URI', 'http://sample.com')); /** 各環境にあわせて変更してくさい. END */ include_once("lib/fb_api_dialog_oauth.php"); include_once("lib/fb_api_oauth_access_token.php"); include_once("lib/fb_api_graph_user.php"); $paramsDialogOauth = new ParamsDialogOauth(); $paramsDialogOauth->setParams(APP_ID , REDIRECT_URI); $paramsDialogOauth->setScope('email,user_birthday'); if(ResponseDialogOauth::isResponse()){ $responseDialogOauth = new responseDialogOauth(); try { $responseDialogOauth->setResponse(); if('' !== ($error = $responseDialogOauth->getError())){ echo $error; }else{ $code = $responseDialogOauth->getCode(); /* アクセストークン取得 */ $paramsOauthAccessToken = new ParamsOauthAccessToken(); $paramsOauthAccessToken->setParams( APP_ID , REDIRECT_URI , APP_SECRET , $code ); $asscessTokenObj = ApiOauthAccessToken::getAccessToken($paramsOauthAccessToken); /* ユーザ情報取得 */ $paramsGraphUser = new ParamsGraphUser(); $paramsGraphUser->setAccessToken($asscessTokenObj->getAccessToken()); $userInfo = ApiGraphUser::getMe($paramsGraphUser); var_dump($userInfo); } } catch (Exception $e) { echo $e->getMessage(); } exit; } header('Content-type: text/html; charset=utf-8'); echo sprintf('<a href="%s">OAuth Link</a>' , ApiDialogOauth::getDialogOAuthUri($paramsDialogOauth));
アクセストークンを取得するまでは、「FacebookとSNS連携!SDKを使わずにOAuth2でアクセストークン取得する/PHP」のsample01.phpとほぼ同じです。
その後、ParamsGraphUserインスタンスにGraph API UserのパラメータをセットしてApiGraphUserクラスに渡し、そしてFacebookからのレスポンスを表示するだけの簡単なものです。
サンプル結果
object(stdClass)#6 (12) { ["id"]=> string(15) "hogehoge" ["birthday"]=> string(10) "dd/mm/yyyy" ["email"]=> string(25) "hoge@yahoo.co.jp" ["first_name"]=> string(4) "太郎" ["gender"]=> string(4) "男性" ["last_name"]=> string(8) "山田" ["link"]=> string(60) "https://www.facebook.com/app_scoped_user_id/hogehoge/" ["locale"]=> string(5) "ja_JP" ["name"]=> string(14) "山田 太郎" ["timezone"]=> int(9) ["updated_time"]=> string(24) "2015-07-04T04:26:06+0000" ["verified"]=> bool(true) }
今回は、サンプルの取得スコープとして誕生日とメールアドレスを設定しているのでそれらも取得できますが、デフォルトでは取得できません。
スコープ(パーミション)にどのようなものがあるかは、Facebook Developers >> Permissions が参考になります。
パーミションについては「Facebook APIで項目が取得できない!パーミション(権限)についてまとめてみた」にブログにしました。
以上
[facebook API 関連記事]