PHP
Facebook
cakephp3

Cakephp3でFacebookSDKをつかったログインを行う

More than 1 year has passed since last update.

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を実装しました。

実装例

MyFbPersistentDataHandler.php
<?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関数の処理を記述します。

UsersController.php
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ログインできました。

参考