今更ながらPHPでFacebook API でログイン処理を書いてみた(v2.8)

【MacOS X 10.11.6 + Facebook API v2.8 + Facebook SDK for PHP v5.0】
必要があってFacebookのログイン処理をPHPで書いてみたので、そのメモです。

1.Facebookに開発者登録してサイトをアプリとして登録

Facebook APIを使うには、Facebookに開発者登録してサイトをアプリとして登録する必要があります。その辺はここでは割愛するので、ご存じない方は下記を参照のこと。
Facebook開発者登録の方法とアプリ作成方法の手順

※この辺の説明はたくさんありますが、サイトによってはキャプチャ画面が古いものもあるので、適宜読み替えが必要。

2.Facebook SDK for PHP v5.0 のインストール

以下から、手動インストール。
facebook for developers | スタートガイド – ウェブSDK
解凍後、サイトのルートに「php-graph-sdk-5.0.0/src/Facebook」をフォルダごとコピーする。

3.PHPでのログイン処理

下記のサイトを参考にしました。コールバックのURLもパス付きで書いてあって、わかりやすいです。
[Facebook SDK for PHP v5.0]を利用してログイン認証をおこなう[Oauth]

ざっと図解すると、こんな感じ。

FacebookAPIの画面遷移

以下、各phpの概要です。

・config.php

Facebook APIで使用する、アプリID,app secret,APIのバージョンを定義。実際にAPIを使用するphpに、require_onceで読み込ませるために共通化。各設定項目とダッシュボードとの対応は、以下の通り。

app_id:アプリID
app_secret:app secret
default_graph_version:APIバージョン

アプリのダッシュボード画面

・index.php

Facebook APIでアプリにログインさせる。実際にはAPI側で、Facebookのログイン及びアプリの認証の可否を確認する画面が表示されるため、ユーザーの意に反してログインされることはない。

・callback.php

Facebook APIからのコールバックを受け取るphp。ここでアクセストークンを取得し、ログインしたユーザー情報を取得する。ユーザーがログインしない/アプリを許可しない場合、取得できないのでindex.phpへのリンクを表示。取得できた場合は、member.phpへ。

・member.php

ログインしたユーザー情報を表示する。

・logout.php

アプリからログアウトする。クッキーを削除して、セッションを破棄することでログアウトになる。

4.コールバックURLをアプリの管理画面に登録

コールバックURLはアプリの管理画面に登録する。左メニューから「プロダクト」>「+製品を登録」>「Facebookログイン」選ぶ。「クライアントOAuth設定」の「有効なOAuthリダイレクトURI」にコールバックURLをフルパスで指定し、右下の「変更を保存」ボタンを押す。

Facebookログインの画面でコールバックURLを指定して、保存する。

4.アクセストークン取得にはコールバックURLの指定が必要

参考サイトのコードをそのまま使ったら、「URLを読み込めません: このURLのドメインはアプリのドメインに含まれていません。このURLを読み込むには、アプリ設定のアプリドメインにすべてのドメインとサブドメインを追加してください。」というエラーが出た。

以下のサイトを参考に、アクセストークン取得のところにコールバックのURIを指定してエラーを解消。

【PHP】 Facebook APIのOauthのエラー解決「URLを読み込めません」「Can’t Load URL」 | codechord

実際にはこんな感じに書き換える。

//アクセストークンを取得する
$accessToken = $helper->getAccessToken('https://c-geru.sakura.ne.jp/c-geru/fb_test/callback.php');

5.デモ

実際の動作デモは、こちらからどうぞ。

6.各ソース

上記4.で述べたように、アクセストークン取得(callback.php)とログイン(index.php)の2箇所でコールバックURLが必要になるため、このサンプルでは、config.phpにコールバックURLを定義して、各phpではセッションから値を取得するようにしました。

・config.php

<?php 
session_start(); 
require_once("Facebook/autoload.php"); 
//コールバックURLをセッションに保存 
$_SESSION['fb_callback_ulr'] = 'https://c-geru.sakura.ne.jp/c-geru/fb_test/callback.php'; 
$fb = new Facebook\Facebook([
  'app_id' => '○○○○○○○○○',
  'app_secret' => '△△△△△△△△△△△△△',
  'default_graph_version' => 'v2.8',
]);

・index.php

<?php 

session_start(); 
header("Content-type: text/html; charset=utf-8"); 

//設定ファイルを読み込み 
require_once("config.php"); 

//コールバックURLの取得 
$callcak_url = $_SESSION['fb_callback_ulr']; 
$helper = $fb->getRedirectLoginHelper();

//オプションによって認証画面の文言が変わる
//$permissions = ['email', 'user_likes','user_posts']; //あなたの公開プロフィール、メールアドレス、タイムライン投稿、いいね!。
//$permissions = ['email', 'user_likes']; //あなたの公開プロフィール、メールアドレス、いいね!。
//$permissions = ['email', 'user_posts'];//あなたのタイムライン投稿。
//$permissions = ['email','user_friends'];//あなたの公開プロフィール、友達リスト、メールアドレス。
//$permissions = ['email'];//あなたの公開プロフィール、メールアドレス。
$permissions = [];//あなたの公開プロフィール。
$loginUrl = $helper->getLoginUrl($callcak_url, $permissions);

echo '<a href="' . $loginUrl . '">ログインする</a>';

・callback.php

<?php 

session_start(); 

header("Content-type: text/html; charset=utf-8"); 

//設定ファイル 
require_once("config.php"); 

//コールバックURLの取得 
$callcak_url = $_SESSION['fb_callback_ulr']; 

//タイムゾーンの設定 
date_default_timezone_set('asia/tokyo'); 

$helper = $fb->getRedirectLoginHelper();

try {
	if (isset($_SESSION['facebook_access_token'])) {
		$accessToken = $_SESSION['facebook_access_token'];
	} else {
		//アクセストークンを取得する
		$accessToken = $helper->getAccessToken($callcak_url);
	}
} catch(Facebook\Exceptions\FacebookResponseException $e) {
	// When Graph returns an error
	echo 'Graph returned an error: ' . $e->getMessage();
	exit;
} catch(Facebook\Exceptions\FacebookSDKException $e) {
	// When validation fails or other local issues
	echo 'Facebook SDK returned an error: ' . $e->getMessage();
	exit;
}

if (isset($accessToken)) {
	//アクセストークンをセッションに保存
	$_SESSION['facebook_access_token'] = (string) $accessToken;
	
	header('Location: member.php');
	exit();
}else{
	echo "<a href='index.php'>はじめのページへ</a>";
}

・member.php

<?php 

session_start(); 
header("Content-type: text/html; charset=utf-8"); 
//設定ファイル 
require_once("config.php"); 

if (isset($_SESSION['facebook_access_token'])) { 
$accessToken = $_SESSION['facebook_access_token']; 
$fb->setDefaultAccessToken($accessToken);
	
	try {
		//取得するユーザ情報の指定
		$response = $fb->get('/me?fields=id,name,first_name,last_name,email,gender');
		$profile = $response->getGraphUser();
		
		//ユーザ画像取得
		$UserPicture = $fb->get('/me/picture?redirect=false&height=200');
		$picture = $UserPicture->getGraphUser();
		
	} catch(Facebook\Exceptions\FacebookResponseException $e) {
		// When Graph returns an error
		echo 'Graph returned an error: ' . $e->getMessage();
		exit;
	} catch(Facebook\Exceptions\FacebookSDKException $e) {
		// When validation fails or other local issues
		echo 'Facebook SDK returned an error: ' . $e->getMessage();
		exit;
	}
	
	$id=$profile['id'];
	$name=$profile['name'];
	$first_name=(isset($profile['first_name'])) ? $profile['first_name'] : '';
	$last_name=(isset($profile['last_name'])) ? $profile['last_name'] : '';
	$email=$profile['email'];
	$gender=(isset($profile['gender'])) ? $profile['gender'] : '';
	$picture_url = $picture['url'];
    
   
	echo "アクセストークン:".$accessToken."";
	echo "ID:".$id."";
	echo "名前:".$name."";
	echo "性別:".$gender."";
	echo "ファーストネーム:".$first_name."";
	echo "ラストネーム:".$last_name."";
	echo "メール:".$email."";//ユーザが未公開・未設定の場合は表示されない
	echo "<img src=".$picture_url.">";
	echo "<a href='logout.php'>ログアウト</a>";

}else{
	header('Location: index.php');
	exit();
}
?>

<!--#_=_を排除する-->
<script type="text/javascript">
if (window.location.hash && window.location.hash == '#_=_') {
  if (window.history && history.pushState) {
      window.history.pushState("", document.title, window.location.pathname);
  } else {
    // Prevent scrolling by storing the page's current scroll offset
    var scroll = {
        top: document.body.scrollTop,
      left: document.body.scrollLeft
    };
    window.location.hash = '';
    // Restore the scroll offset, should be flicker free
    document.body.scrollTop = scroll.top;
    document.body.scrollLeft = scroll.left;
  }
}
</script>

・logout.php

<?php
session_start();
 
header("Content-type: text/html; charset=utf-8");

//セッション変数を全て解除
$_SESSION = array();
 
//セッションクッキーの削除
if (isset($_COOKIE["PHPSESSID"])) {
    setcookie("PHPSESSID", '', time() - 1800, '/');
}
 
//セッションを破棄する
session_destroy();
 
echo "ログアウトしました。"; 
echo "<a href='index.php'>はじめのページへ</a>";

「今更ながらPHPでFacebook API でログイン処理を書いてみた(v2.8)」への4件のフィードバック

  1. 「URLを読み込めません: このURLのドメインはアプリのドメインに含まれていません。このURLを読み込むには、アプリ設定のアプリドメインにすべてのドメインとサブドメインを追加してください。」というエラーにずっとハマっています。

    サイトに書いてる参考サイトなども参照しましたが、
    いまだできません。
    ご教示いただけませんか。
    よろしくお願いいたします。

    1. こんにちは。

      改めて設定を見てみましたが、この記事に書いていない部分だと、ダッシュボード>設定>ベーシックの「サービス規約のURL」欄に https://c-geru.sakura.ne.jp/ と入力されているぐらいですかね。。。

      あとは・・・

      ・この記事はhttpsベースで書いているので、httpsでやってみる。
      ・セッションから config.php の’fb_callback_ulr’がきちんと取得出来ているか確認する。

      とかでしょうか?

  2. callback.phpにて「Cross-site request forgery validation failed. Required param “state” missing from persistent data」エラーが出てしまいます。
    解決策をご教授頂きたいです。

コメントは停止中です。