我或多或少在一周后就遇到了问题,当我离开时,打开我的应用程序页面,但可能有4或5个小时没有使用它,然后每次在控制台中显示以下内容时返回请求(点击按钮加载类似的内容):
{
"error":{
"type":"Illuminate''Session''TokenMismatchException",
"message":"",
"file":"C:''xampp182''htdocs''mysite''app''filters.php",
"line":97
}
}
我在POST请求中使用CSRF protecció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是不同的,但有没有办法重新生成或将两个token都设置为相同的值?
这就是CSRF保护的工作原理。会话生存期结束后,它将生成新的令牌。一般情况下,4-5小时内没有人会填写表格。如果您这样做只是为了在本地主机上进行测试,那么您可以将app/config/session
中的lifetime
更改为更高的值,它应该可以工作。
否则,您可能会更改:
throw new Illuminate'Session'TokenMismatchException; //Line 97
变成类似的东西
return Redirect:back()->withInput(Input::except('token'))->with('_token',Session::token());
我在登录时也遇到了这个问题。这个异常不时发生,所以我停下来尝试复制它。我通过这样做成功了:
首先我加载登录页面。
然后我删除了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.');
}
});
因此,在页面重新加载之后,将创建一个新的会话并解决问题。
只需将以下代码放入过滤器:
if (Session::token() !== $token)
{
return Redirect::back()->withInput(Input::except('_token'));
}