跨站点请求伪造验证失败。缺少必需的参数 "state"。 Yii-2

Cross-site request forgery validation failed. Required param "state" missing. Yii-2

所以我在我的控制器中有登录(这里称为 facebook)操作、登录回调操作和显示操作,我想在其中使用 Facebook 查看信息 API。我已经阅读了我的问题并发现我的会话似乎已关闭,但我还了解到在 Yii-2 中它们会在应用程序初始化时自动打开。我也在没有框架的情况下尝试过,效果很好。也许有人在 Yii-2 中遇到过这样的问题?

登录操作

**public function actionFacebook()**
{
    $fb = new Facebook([
        'app_id' => 'my_app_id',
        'app_secret' => 'my_app_secret',
        'default_graph_version' => 'v2.5',
    ]);
    $helper = $fb->getRedirectLoginHelper();
    $permissions = ['user_friends']; // optional
    $loginUrl = $helper->getLoginUrl('http://myblog.local/site/callback', $permissions);

    return $this->render('facebook', [
       'loginUrl' => $loginUrl,
    ]);

}

回调操作

**public function actionCallback()**
{
    $fb = new Facebook([
        'app_id' => 'my_app_id',
        'app_secret' => 'my_app_secret',
        'default_graph_version' => 'v2.5',
    ]);

    $helper = $fb->getRedirectLoginHelper();
    try {
        $accessToken = $helper->getAccessToken();
    } catch(FacebookResponseException $e) {
        // When Graph returns an error
        echo 'Graph returned an error: ' . $e->getMessage();
        exit;
    } catch(FacebookSDKException $e) {
        // When validation fails or other local issues
        echo 'Facebook SDK returned an error: ' . $e->getMessage();
        exit;
    }

    if (isset($accessToken)) {
        // Logged in!
        $_SESSION['facebook_access_token'] = (string) $accessToken;

        // Now you can redirect to another page and use the
        // access token from $_SESSION['facebook_access_token']

        return $this->redirect('/site/display',302);
    }
}

显示操作(我想使用Facebook查看信息API)

public function actionDisplay()
{
    $fb = new Facebook([
        'app_id' => '491899464333863',
        'app_secret' => 'f684b9467c548991cc3a91e028163e15',
        'default_graph_version' => 'v2.5',
    ]);

    // Sets the default fallback access token so we don't have to pass it to each request
    $fb->setDefaultAccessToken($_SESSION['facebook_access_token']);

    try {
        $response = $fb->get('/me');
        $userNode = $response->getGraphUser();
    } catch(FacebookResponseException $e) {
        // When Graph returns an error
        echo 'Graph returned an error: ' . $e->getMessage();
        exit;
    } catch(FacebookSDKException $e) {
        // When validation fails or other local issues
        echo 'Facebook SDK returned an error: ' . $e->getMessage();
        exit;
    }

    return $this->render('display', [
        'userName' => $userNode,
    ]);
}

在 Yii2 中,如果您之前没有使用 session_start() 打开会话,则更改 $S_SESSION 内容将不起作用。

When you access session data through the session component, a session will be automatically opened if it has not been done so before. This is different from accessing session data through $_SESSION, which requires an explicit call of session_start().

来源: http://www.yiiframework.com/doc-2.0/guide-runtime-sessions-cookies.html

Yii2 有一个 class 来管理会话。因此,您可以将 accesToken 存储在 callback 操作中:

$session = Yii::$app->session;
$session['accessToken'] =  $accessToken; 

然后,在您的显示操作中:

$session = Yii::$app->session;
[...]
$fb->setDefaultAccessToken($session['accessToken']);

请记住,您可以使用调试工具栏检查 $_SESSION 内容。

更多信息:http://www.yiiframework.com/doc-2.0/yii-web-session.html

您真的应该设置自己的 PersistentDataInterface。有关详细信息,请参阅此答案: