session_start()
を使わずに、FacebookSDKを使ったログインを処理します。
環境
- PHP 7.0.9
- CakePHP 3.3.2
- facebook/php-sdk-v4 5.2.0
問題
CakePHPでFacebook SDK for PHPのドキュメント通りに実装すると、callback処理の時にCross-site request forgery validation failed. Required param “state” missing
というエラーが発生してログイン処理できません。
これは、loginUrl生成時にstate
という値がセッションに設定されていなかったために発生していました。
これを解決するために調べてみると、ほとんどの場合はsession_start()
を実行してからloginUrl生成→callback関数とすればイケるよ!と書いてありましたが、これだと都度session_start()
しないといけません。何だかなぁと思っていたらクラスを作っても対応できるとのことなので、その時の方法をメモしておきます。
対応方法
new Facebook
をする時に、persistent_data_handler
を指定することで、session_start()
をすることなくCakePHPのSessionを使用しながらFacebookログインできました。
例えば、以下のようなsrc/Handler/MyFbPersistentDataHandler
を実装しました。
実装例
<?php
namespace App\Handler;
use Facebook\PersistentData\PersistentDataInterface;
class MyFbPersistentDataHandler implements PersistentDataInterface
{
private $_session = null;
public function __construct($session)
{
$this->_session = $session;
}
public function get($key)
{
return $this->_session->read($key);
}
public function set($key, $value)
{
$this->_session->write($key, $value);
}
}
使い方
あとはドキュメント通りにログイン画面の生成と、callback関数の処理を記述します。
use App\Handler\MyFbPersistentDataHandler;
...
public function createFbUrl(){
...
$fb = new Facebook([
'app_id' => FACEBOOK_API_ID,
'app_secret' => FACEBOOK_APP_SECRET,
'default_graph_version' => DEFAULT_GRAPH_VERSION,
'persistent_data_handler' => new MyFbPersistentDataHandler($this->request->session())
]);
$helper = $fb->getRedirectLoginHelper();
...
}
public function fbLoginCallback(){
...
$fb = new Facebook([
'app_id' => FACEBOOK_API_ID,
'app_secret' => FACEBOOK_APP_SECRET,
'default_graph_version' => DEFAULT_GRAPH_VERSION,
'persistent_data_handler' => new MyFbPersistentDataHandler($this->request->session())
]);
$helper = $fb->getRedirectLoginHelper();
...
}
これでFacebookログインできました。