Laravel 4,使用CSRF在filters.php中使用Token不匹配异常

时间:2014-09-26 16:15:43

标签: php laravel laravel-4 csrf-protection

我有一个问题,因为1周或多或少,当我打开我的应用程序的页面但没有使用它可能4或5个小时并返回发出请求(点击一个按钮来加载某些东西或东西)像这样)每次在控制台中显示:

{
"error":{
    "type":"Illuminate\\Session\\TokenMismatchException",
    "message":"",
    "file":"C:\\xampp182\\htdocs\\mysite\\app\\filters.php",
    "line":97
    }
}

我在我的POST请求中使用CSRFprotección传递ajax请求此配置

$.ajax({
        url: '/path/to/file',
        type: 'default GET (Other values: POST)',
        dataType: 'default: Intelligent Guess (Other values: xml, json, script, or html)',
        data: {param1: 'value1'},
        headers: {
            'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
        },
    })
    .done(function() {
        console.log("success");
    })
    .fail(function() {
        console.log("error");
    })
    .always(function() {
        console.log("complete");
    });

这是我的 filters.php

/*
|--------------------------------------------------------------------------
| CSRF Protection Filter
|--------------------------------------------------------------------------
|
| The CSRF filter is responsible for protecting your application against
| cross-site request forgery attacks. If this special token in a user
| session does not match the one given in this request, we'll bail.
|
*/

Route::filter('csrf', function($route, $request)
{
    if (strtoupper($request->getMethod()) === 'GET')
    {
        return; // get requests are not CSRF protected
    }

    $token = Request::ajax() ? Request::header('x-csrf-token') : Input::get('_token');

    if (Session::token() != $token)
    {
        throw new Illuminate\Session\TokenMismatchException; //Line 97
    }
});

修改

我看到问题,Session :: token()和$ token是不同的,但是有没有办法重新生成或放置具有相同值的两个标记?

3 个答案:

答案 0 :(得分:0)

这就是CSRF保护的工作原理。会话生命周期后,它会生成新令牌。通常没有人会填写表格4-5个小时。如果您只是为了在本地主机上进行测试,则可以将lifetime中的app/config/session更改为更高的值,它应该可以正常工作。

否则你可能会改变:

throw new Illuminate\Session\TokenMismatchException; //Line 97

这样的事情

 return Redirect:back()->withInput(Input::except('token'))->with('_token',Session::token());

答案 1 :(得分:0)

我在登录时遇到了这个问题。这个异常不时发生,所以我停下来试图重现它。这样做我成功了:

首先我加载登录页面。

然后我删除了cookie。

然后,在没有重新加载登录页面的情况下,我输入了用户名和密码并尝试登录。

因为会话被删除了(当我删除cookie时),这段代码不会通过是正常的,它会抛出TokenMismatchException。

Route::filter('csrf', function() {
    if ( Session::getToken() != Input::get('_token')) {
        throw new Illuminate\Session\TokenMismatchException;
    }
});

所以,我为解决我的问题所做的是添加一个重定向到登录页面,并带有一条消息通知用户该会话可能已过期。

Route::filter('csrf', function() {
    if ( Session::getToken() != Input::get('_token')) {
        return Redirect::to('/admin/login')->with('warning', 'Your session has expired. Please try logging in again.');
    }
});

因此,在页面重新加载后,会创建一个新会话并解决问题。

答案 2 :(得分:0)

只需将以下代码放入过滤器:

if (Session::token() !== $token)
{
    return Redirect::back()->withInput(Input::except('_token'));
}