多站点使用 laravel
导致 CSRF
在cookies中的键值冲突,然后爆 Illuminate\Session\TokenMismatchException
错误
问题
这个问题一直间歇性出现,也是最近才意识到因为公司内部各个子站开始推行 laravel
。
于是重新看了文档找到以下关键
Laravel stores the current CSRF token in a
XSRF-TOKEN
cookie that is included with each response generated by the framework.
从此可知 laravel
会向 cookies
写入一个键名为 XSRF-TOKEN
的 验证字段,而我们的各站点如果默认都使用此字段就会出现,在A站生成此字段值,在B站使用,然后CSRF报错。
解决
重写 Illuminate\Foundation\Http\Middleware\VerifyCsrfToken
中的 addCookieToResponse
这个方法即可
具体做法
我们只要在 \app\Http\Middleware\VerifyCsrfToken.php
这个文件中,重写此方法即可:
<?php
namespace App\Http\Middleware;
use Symfony\Component\HttpFoundation\Cookie;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
class VerifyCsrfToken extends BaseVerifier
{
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array
*/
protected $except = [
];
/**
* Add the CSRF token to the response cookies.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Http\Response $response
* @return \Illuminate\Http\Response
*/
protected function addCookieToResponse($request, $response)
{
$config = config('session');
$response->headers->setCookie(
new Cookie(
//在这改成 cookies 中唯一的键即可如 ‘GN_XSRF-TOKEN’
'XSRF-TOKEN', $request->session()->token(), time() + 60 * $config['lifetime'],
$config['path'], $config['domain'], $config['secure'], false
)
);
return $response;
}
}