Php 会话超时后出现laravel csrf令牌不匹配异常
在我们的Laravel5应用程序中,登录是通过ajax进行的。若用户在会话到期前注销并重新登录,则一切正常。但如果用户注销并在会话到期前保持该页面空闲,则如果用户尝试重新登录,将获得Php 会话超时后出现laravel csrf令牌不匹配异常,php,ajax,session,laravel,Php,Ajax,Session,Laravel,在我们的Laravel5应用程序中,登录是通过ajax进行的。若用户在会话到期前注销并重新登录,则一切正常。但如果用户注销并在会话到期前保持该页面空闲,则如果用户尝试重新登录,将获得csrfTokenMismatch异常 我知道在verifyCsrfToken中间件中,laravel检查会话是否与csrf令牌匹配。同样在Guard.php logout()方法中,会话将在注销时被清除 因此,我的问题是: 会话真的在注销时刷新了吗?如果是的话,为什么用户仍然可以在我设置的会话过期之前重新登录 会话
csrfTokenMismatch
异常
我知道在verifyCsrfToken
中间件中,laravel检查会话是否与csrf令牌匹配。同样在Guard.php logout()
方法中,会话将在注销时被清除
因此,我的问题是:
会话真的在注销时刷新了吗?如果是的话,为什么用户仍然可以在我设置的会话过期之前重新登录
会话过期时,csrf令牌会发生什么情况
最后,这个问题通常是如何优雅地处理的
提前谢谢 有一个名为XSRF-Token的cookie,默认生存时间为2小时 我通过修改App/Exceptions/Handler.php处理登录表单上的TokenMissMatchException,如下所示:
// ....
use Illuminate\Session\TokenMismatchException;
// ....
public function render($request, Exception $e)
{
if($e instanceof TokenMismatchException) {
$uri = \Route::current()->uri();
if($uri == "login") {
return redirect()->route('your.login.route')
->withErrors("Login Form was open too long.
Please try to login again");
}
}
return parent::render($request, $e);
}
在您的情况下,我认为您将真正受益于此: 我个人处理类似这样的非ajax情况,您可以针对ajax请求对其进行调整,以返回一些有用的json用于错误处理:
public function render($request, Exception $e)
{
if ($e instanceof \Illuminate\Session\TokenMismatchException) {
return redirect()
->back()
->withInput($request->except('_token'))
->withMessage('Your explanation message depending on how much you want to dumb it down, lol! ');
}
return parent::render($request, $e);
}
}
这个答案是关于5.4版的,可能是以前的版本,但我还没有测试过 问题的根源是CSRF令牌在客户端过期,这使得使用该令牌向服务器发送的任何邮件都失败 如果您使用的是AJAX,那么可以使用默认情况下不进行CSRF验证的API路由 您可以关闭特定URI的CSRF验证。在本例中,我将关闭
/logout
的CSRF验证。如果您确实希望从验证中排除某些URI,那么这种方法可以很好地工作
app/Http/Middleware/VerifyCsrfToken.php
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array
*/
protected $except = [
'/logout'
];
app/Exceptions/Handler.php
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $exception
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $exception)
{
if($exception instanceof \Illuminate\Session\TokenMismatchException){
// token mismatch is a security concern, ensure logout.
Auth::logout();
// Tell the user what happened.
session()->flash('alert-warning','Your session expired. Please login to continue.');
// Go to login.
return redirect()->route('login');
}
return parent::render($request, $exception);
}
config/session.php
/*
|--------------------------------------------------------------------------
| Session Lifetime
|--------------------------------------------------------------------------
|
| Here you may specify the number of minutes that you wish the session
| to be allowed to remain idle before it expires. If you want them
| to immediately expire on the browser closing, set that option.
|
*/
'lifetime' => 1,