Yii2中没有cookie的CSRF验证

问题描述 投票:0回答:1

在我的Yii2应用程序中,有用户提交的表格。该站点已启用CSRF验证,但是如果用户禁用了Cookie,则会引发错误。处理这种情况的最佳方法是什么?我真的不想禁用CSRF验证以确保仅从我的站点提交表单。不涉及登录过程。对于用户而言,这只是一次性使用情况。谢谢。

yii2 csrf
1个回答
0
投票

您可以通过将enableCsrfCookie组件的yii\web\Request属性设置为false来强制应用程序将CSRF令牌存储在会话中,而不是cookie中。您可以在web.php配置中执行此操作:

$config = [
    // ...
    'components' => [
        'request' => [
            'enableCsrfCookie' => false,
        ],
        // ...
    ],
    // ...
];

但这会导致应用为每个请求启动会话。默认情况下,会话也使用cookie来存储会话ID,因此,如果您想避免使用任何cookie,最终可能不会有太大的改善。]

您还可以扩展yii\web\Request并覆盖其方法generateCsrfToken()loadCsrfToken()以对令牌使用不同的存储。但是请记住,默认情况下无法识别来自同一会话的请求。您必须将某种sessionId保存在客户端中,然后将其发送回服务器,以便能够将提交表单的请求与CSRF令牌和生成CSRF令牌的请求配对。

另一种可能性是关闭标准CSRF保护并实施您自己的形式保护。例如,您可以在应用程序配置中存储一些密钥。然后,在生成表单时,将使用yii\base\Security::hashData()方法将时间戳添加到表单中:

$timestamp = Yii::$app->security->hashData(time(), $yourSecurityKey);
Html::hiddenInput('my-csrf', $timestamp);

然后您可以在控制器操作中验证它:

$timestamp = Yii::$app->security->validateData(
   Yii::$app->request->post('my-csrf'),
   $yourSecurityKey
);

if ($timestamp === false || $timestamp < (time() - $timeLimitInSeconds)) {
     //Do something when CSRF validation is not valid (for example throw bad request exception)
}

// continue form processing
© www.soinside.com 2019 - 2024. All rights reserved.