LoginSignup
4
4

More than 5 years have passed since last update.

CakePHPでFacebook php-sdk-v4使ってもstateなんちゃらで怒られないようにする

Posted at

今更感も否めませんが、CakePHP2.x系の話。3でも同じことが起きるのかもしれない。

問題の概要

既存のCakePHP2アプリ(Session管理にRedisを利用)にfacebook/php-sdk-v4(~5.0)を使ってソーシャルログイン機能を追加しようとしても

Cross-site request forgery validation failed. Required param "state" missing from persistent data.

という例外が発生して、上手くアクセストークンを取得できない。

なぜか

どうも、CakePHPのSessionとFacebookSDKのSessionが競合しているようで、SDKのDocument通りsession_start()とかしたら、今度はCakePHPのSessionが上手く機能しなくなり、setFlash等のメッセージが表示されないといったトラブルが起きる。

どうする

php-sdk-v4のセッション管理をCakePHPっぽく書いてあげれば問題を回避できる。
具体的には、FacebookSessionPersistentDataHandlerを修正する。

FacebookSessionPersistentDataHandler.php
    /**
     * @inheritdoc
     */
    public function get($key)
    {
        if (isset($_SESSION[$this->sessionPrefix . $key])) {
            return $_SESSION[$this->sessionPrefix . $key];
        }
        return null;
    }

    /**
     * @inheritdoc
     */
    public function set($key, $value)
    {
        $_SESSION[$this->sessionPrefix . $key] = $value;
    }

ここを

FacebookSessionPersistentDataHandler.php
    /**
     * @inheritdoc
     */
    public function get($key)
    {
        if(\CakeSession::read($this->sessionPrefix . $key)){
            return \CakeSession::read($this->sessionPrefix . $key);
        }
        return null;
    }

    /**
     * @inheritdoc
     */
    public function set($key, $value)
    {
        \CakeSession::write($this->sessionPrefix.$key,$value);
    }

このような形でCakeSessionに書き換える。

ただ、これだけでは上手く行かない場合があるので、その時はFacebookRedirectLoginHelper::getAccessToken, ::getLoginUrlなど、Sessionを使うメソッドの呼び出し前に

CakeSession::start();
#あるいは
\CakeSession::start()

で明示的にSessionをスタートさせてあげれば良かった。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4