为啥 Laravel 4 CSRF 令牌不起作用?

Posted

技术标签:

【中文标题】为啥 Laravel 4 CSRF 令牌不起作用?【英文标题】:Why Laravel 4 CSRF token is not working?为什么 Laravel 4 CSRF 令牌不起作用? 【发布时间】:2013-08-25 03:42:53 【问题描述】:

我实际上是在玩 Laravel 4。现在我在表单发布上实现了 CSRF 令牌安全性。

问题在于,从会话Session::token() 中生成的令牌始终相同的意义上说,这实际上并不起作用,因此当我尝试重新提交表单甚至从另一台服务器发布表单时,安全检查不起作用Session::token() != Input::get('_token') (filters.php)

有人遇到过这个问题吗?

编辑: 好的,我找到了这个解释。每个机器/会话的令牌实际上是不同的。现在更有意义了:) 感谢大家的帮助

【问题讨论】:

【参考方案1】:

在表单中,您必须像这样创建令牌:

<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">

之后,令牌将与输入一起发送。 因此,当您收到输入时,您必须像这样检查令牌:

Route::post('register', array('before' => 'csrf', function()

    return 'You gave a valid CSRF token!';
));

这样,您将在访问路由之前放置一个过滤器来检查 CSRF 令牌。

从 Laravel 文档中得到这个,正确的 here

【讨论】:

感谢您的回答。我做了所有这些,但我的问题是关于未更新的令牌本身。即使我刷新页面,令牌仍然相同,因此过滤器将始终返回 true。【参考方案2】:

提交表单后,在处理完表单后,您应该更改 CSRF 令牌,例如 Session::put('_token', md5(microtime())); 这将防止表单重新提交。有关更多信息,您可以查看 this 和 this

【讨论】:

感谢您的回答。事实上,到目前为止,这是唯一可行的方法,但如果我们仍然需要关心这些细节,我认为给开发人员开箱即用的 csrf-token 安全检查真的很愚蠢。这应该开箱即用:(再次感谢 哇。我刚刚对其进行了测试,并多次获得了相同的令牌。您必须想知道他们认为 CSRF 令牌的意义是什么......我想知道它是否已在 5 中修复。【参考方案3】:

我在 app/filter.php 中以这种方式使用内置的 regenerateToken 函数:

Route::filter('csrf', function()

    if (Session::token() != Input::get('_token'))
    
        Session::regenerateToken();
        return *Redirect / Exception*
    
    Session::regenerateToken();
);

使用输入重定向时的另一个注意事项!

在 laravel 4 中,当您以这种方式使用 Form::open(...) 时会生成令牌:

public function token()

    return $this->hidden('_token', $this->csrfToken);

所以它使用了一个隐藏的输入,如果存在的话,它会从 Input::old 函数中设置它的值。

为了防止这种情况,如果您不想使用已经过时的令牌制作表单,则需要使用 Input::except('_token'):

return Redirect::route('routename')->withInput(Input::except('_token'));

【讨论】:

【参考方案4】:

当您使用 Blade 创建表单时,_token 会自动呈现在表单内

<?php echo Form::open(array('url' => '/', 'files' => true, 'id' => 'shareForm', 'method' => 'post')) ?>
...
html
...
 <?php echo Form::close() ?>

【讨论】:

以上是关于为啥 Laravel 4 CSRF 令牌不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

Laravel - CSRF 与会话令牌不匹配

如何在 Laravel 中禁用 CSRF 令牌以及为啥我们必须禁用它?

为啥我在 laravel 中运行测试时收到“CSRF 令牌不匹配”?

为啥我的 CSRF 令牌与 Laravel 和 Sanctum 不匹配?

如何在 VueJS 文件中添加 Laravel CSRF 令牌? [复制]

spring security 3.2.0 csrf 令牌在 freemarker 模板中不起作用