我的$ request->输入(_token)在从文件切换到数据库会话时与$ request-> session() - > toke()不匹配。
这导致CSRF TokenMismatchException。当从数据库切换回文件sessons驱动程序时,不会发生不匹配。
有谁知道为什么我会遇到这种不匹配,可能还有解决方法? :) 我做了什么:
<小时/> 使用Laravel 5.0
php artisan session:table:创建了Laravel会话表 composer dump-autoload php artisan配置:清除 php arisan config:cache
我的session.php配置如下所示:
return [
'driver' => 'database',
'lifetime' => 120,
'expire_on_close' => false,
'encrypt' => false,
'files' => storage_path().'/framework/sessions',
'connection' => null,
'table' => 'laravel_session',
'lottery' => [2, 100],
'cookie' => 'laravel_session',
'path' => '/',
'domain' => null,
'secure' => false,
];
VerifyCsrfToken Illuminate \ Foundation \ Middleware
protected function tokensMatch($request)
{
$tok = $request->input('_token') ; //4ExGXl9mRM75d7brfQhgIWcQzsSVjnUHDoDcKJxp
$tokhead = $request->header('X-CSRF-TOKEN');
$sessToken = $request->session()->token();//57DLb3uTs8brVPKpBxor14Hg0ZvQPpYW3flktP86
$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);
切换到数据库sesseio驱动程序后,数据库表填充了数据:
SELECT id, payload, last_activity, user_id FROM kartserver_2.laravel_session;
d33d5782e1eed56771baa56f9410a24b9e628ff6 YToxNzp7czo2OiJfdG9rZW4iO3M6NDA6Ikh6dUc4WG1PUDFZalRHY0QwcW5QZzlFSGRUSkJ3ZmVOUkVjM0RJVk0iO3M6NToiZmxhc2giO2E6Mjp7czozOiJvbGQiO2E6MDp7fXM6MzoibmV3IjthOjA6e319czoyMDoicGFzc3dvcmRSZXF1aXJlbWVudHMiO086NDE6Ikhhd2tTb2Z0d2FyZVxTZWN1cml0eVxQYXNzd29yZFJlcXVpcmVtZW... 1487315670 1862
我在html中生成csrf_tokens
<input type="hidden" name="_token" id="_token" value="{!! csrf_token() !!}">
答案 0 :(得分:1)
如果您使用的是Laravel 5.4 *并且偶然发现了这个问题,那么您需要做的就是
1-更新.env文件
# file = .env in your project root
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=testdb
DB_USERNAME=db_user
DB_PASSWORD=secret_pass
SESSION_DRIVER=database
请注意下一步中需要的DB_CONNECTION设置。
2-更新config / session.php文件 其中connection param应该包含您在.env文件中用于DB_CONNECTION的字符串
# file = config/session.php
'driver' => env('SESSION_DRIVER', 'database'),
'connection' => 'mysql', // this is from DB_CONNECTION in .env file
3-生成会话表
php artisan session:table
// run the migration !!! very very important
php artisan migrate
4-如果由于某种原因您决定在不使用迁移的情况下手动创建表,请使用此SQL。这是非常重要的一步,错误的表会导致各种问题。 主要是不要像往常一样手动创建一个id列作为bigint的表,会话表是不同的。
DROP TABLE IF EXISTS `sessions`;
create table sessions
(
id varchar(255) not null,
user_id int(10) unsigned null,
ip_address varchar(45) null,
user_agent text null,
payload text not null,
last_activity int not null,
constraint sessions_id_unique
unique (id)
)
这应该在将db设置为会话保存路径后解决令牌不匹配异常。
答案 1 :(得分:0)
它们应该是不同的:)
您有一个GET /pay50dollarToHarry
(非常愚蠢的示例)端点,在访问时触发。当进入像stackoverflow这样的论坛并发布如下图像时:
<img src="youdomain.com/pay50dollarToHarry />
浏览器将访问该链接以获取图像并将转移50美元。通过在表单中使用csrf标记,这不能从其他页面完成。
P.S。请不要更改框架/库中的代码:它们将在更新时被覆盖。这是不好的做法。原来的功能:
/**
* Determine if the session and input CSRF tokens match.
*
* @param \Illuminate\Http\Request $request
* @return bool
*/
protected function tokensMatch($request)
{
$token = $this->getTokenFromRequest($request);
return is_string($request->session()->token()) &&
is_string($token) &&
hash_equals($request->session()->token(), $token);
}