因为我已经将laravel更新为5.4,所以我不断得到:
TokenMismatchException in VerifyCsrfToken.php line 68
异常抛出。经过一些挖掘和阅读大量帖子和github问题后,我发现我的令牌不匹配:)。关键是我的laravel应用程序设置了令牌的加密版本" XSRF-TOKEN"而不是它的普通(X-CSRF-TOKEN)对应物和助手csrf_token()
吐出普通令牌,因此不匹配令牌。令人困惑的是,当我得到XSRF-TOKEN(缺少X-)时,为什么文档提到了X-XSRF-TOKEN?所以问题是:
csrf_token()
? (这是否重要,因为连接是加密的?)$excepted
\MiddleWare\EncryptCookies.php
下的ca.company.project
可行选项,或者您可以建议更好的解决方案吗? (这使我们回到问题#3)我很抱歉这么多问题,并提前致谢!
在多次重读我的问题之后,我得出结论,他们不够清楚并且没有遵守标题。我的问题是不匹配的令牌,我认为我的疑虑被清除会让我找到解决方案,我感谢@ThomasMoors的耐心和帮助。我会接受他的回答,虽然我以不同的方式解决了我的问题,但是他的帮助使我找到了解决方案!我还发布了自己的答案,其中描述了我如何解决我的问题以帮助其他人遇到类似的问题!
答案 0 :(得分:2)
The function that checks the token尝试使用密钥_token
在请求 plain 中找到(1),如果找不到,则将尝试使用密钥X-CSRF-TOKEN
查看(2)请求标头。要匹配的令牌存储在会话where the session lives depends on your config。
/**
* Determine if the session and input CSRF tokens match.
*
* @param \Illuminate\Http\Request $request
* @return bool
*/
protected function tokensMatch($request)
{
$token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN');
if ( ! $token && $header = $request->header('X-XSRF-TOKEN'))
{
$token = $this->encrypter->decrypt($header);
}
return StringUtils::equals($request->session()->token(), $token);
}
问:缺少“X-”有什么含义吗?
A :Laravel将当前的CSRF令牌存储在XSRF-TOKEN cookie中,即 包含在框架生成的每个响应中。您可以使用 用于设置X-XSRF-TOKEN请求标头的cookie值。
这个cookie主要是为了方便起见,因为有些JavaScript 框架和库,如Angular和Axios,自动放置 它在X-XSRF-TOKEN标题中的值。
问:如何将令牌的加密版本更改为普通版? (无论问题#3如何)
A :如上面的代码(来自github)\Illuminate\Contracts\Encryption\Encrypter
有一个名为decrypt()
的函数可以执行此操作
问:我是否应该尝试从加密的令牌中创建一个普通令牌,或者更好地加密csrf_token()? (这是否重要,因为连接已加密?)
A :没关系,因为令牌里面没有数据,它只是源自您网站的合法请求的标识符,而不是来自其他域的某些ajax / xhr调用。在https://en.wikipedia.org/wiki/Cross-site_request_forgery
上阅读更多内容问:在\ MiddleWare \ EncryptCookies.php中将$ XSL下的“XSRF-TOKEN”列为可行选项,或者您可以建议更好的解决方案吗? (这使我们回到问题#3)
A :令牌没有理由随时进入Cookie,是吗?
似乎从5.0到5.4确实在上面的函数中有has changed。它现在看起来像这样:
protected function tokensMatch($request)
{
$token = $this->getTokenFromRequest($request);
return is_string($request->session()->token()) &&
is_string($token) &&
hash_equals($request->session()->token(), $token);
}
答案 1 :(得分:0)
虽然我无法确定问题的根源(由于缺乏框架经验),但我终于可以解决我的问题了。到目前为止,我错过了一些中间件类被移动到 app / Http / Kernel.php 文件中的不同中间件组(我的问题可能是因为< strong>他们加载的顺序已经改变,或者可能是因为其中一些根本没有加载?)。我很确定,这是我的问题的原因,因为我不断重新加载我的页面以及清除github上建议的缓存,这是由jeremykenedy建议的。建议是调用以下命令:
sudo rm -rf storage/framework/sessions/*
sudo php artisan cache:clear
sudo php artisan clear-compiled
sudo composer dump-autoload
所有你解决类似问题的人可能已经遇到过数百次了。我经常发现的另一个建议是更改存储文件夹的权限,这可能有助于解决类似的问题!
答案 2 :(得分:0)
我发现了有关令牌不匹配异常的有趣事情。我在 AppServiceProvider 中将日期时间伪造为:
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Carbon::setTestNow('2000-07-05 4:00 pm');
}
此后,我无法登录到laravel应用程序。否则只需一个命令即可解决令牌不匹配异常。
php artisan config:clear