首页 文章

为什么Laravel 4 CSRF令牌不起作用?

提问于
浏览
9

我实际上正在玩Laravel 4.现在我在表单帖子上实现了CSRF令牌安全性 .

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

有人已经遇到过这个问题?

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

4 回答

  • 9

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

    <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

  • 3

    提交表单时,在处理表单后,您应该更改CSRF令牌,如 Session::put('_token', md5(microtime())); 这样可以防止表单重新提交..有关详细信息,请参阅thisthis

  • 1

    我在app / filter.php中使用内置的regenerateToken函数:

    Route::filter('csrf', function()
    {
        if (Session::token() != Input::get('_token'))
        {
            Session::regenerateToken();
            return *Redirect / Exception*
        }
        Session::regenerateToken();
    });
    

    Another note when you redirect with input!

    在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'));
    
  • 0

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

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

相关问题