2

我正在使用 Vue 开发一个新的前端来访问我现有的 Laravel 7 应用程序,该应用程序使用 Sanctum 进行身份验证。

前端位于 app.example.com,后端移至 api.example.com。CORS 中间件和 Sanctum 已正确配置为允许 app.example.com,到目前为止一切顺利。

GET/sanctum/csrf-cookie看起来不错,但是,它似乎并没有真正设置 cookie,导致随后对 API 的请求返回 419。

const config = { withCredentials: true };
const api = process.env.NODE_ENV === 'production' ? 'https://api.example.com' : 'http://localhost:9000';

axios.get(api + '/sanctum/csrf-cookie', config)
  .then(() => axios.post(api + '/login', data, config))
  .then(response => response.json())
  .then(response => { console.log('json', response); });

控制台日志: 在此处输入图像描述

来自 /sanctum/csrf-cookie 的响应标头: 来自 /sanctum/csrf-cookie 的响应

devtools 中没有列出任何 cookie: 在此处输入图像描述

更新 1:之前没有注意到这一点;响应标题中每个旁边的警告图标Set-Cookie显示“此 set-cookie 的域属性对于当前主机 url 无效。”

4

2 回答 2

3

简短回答:不应在 cookie 域属性中指定端口。

长答案:Laravel Sanctum 使用VerifyCsrfToken中间件发送和验证 CSRF 令牌,该令牌在将 cookie 添加到响应时使用会话配置值

protected function addCookieToResponse($request, $response)
{
    $config = config('session');

    if ($response instanceof Responsable) {
        $response = $response->toResponse($request);
    }

    $response->headers->setCookie(
        new Cookie(
            'XSRF-TOKEN', $request->session()->token(), $this->availableAt(60 * $config['lifetime']),
            $config['path'], $config['domain'], $config['secure'], false, false, $config['same_site'] ?? null
        )
    );

    return $response;
}

config/session.php

'domain' => env('SESSION_DOMAIN', null),

.env

SESSION_DOMAIN=localhost:8080

同一主机上的 Cookie 不能通过端口来区分。因为我在 cookie 域中指定了端口,所以浏览器将 cookie 标记为具有无效域。删除端口就可以了。

于 2020-05-07T15:11:06.157 回答
0

为了解决这个问题,我在浏览器中将 vue cli 主机 127.0.0.1:8080 更改为 localhost:8080,在 axios 中,基本 url 现在是 http://localhost:7000,它用于 laravel api。

之后我在 .env laravel 中设置 SESSION_DOMAIN=localhost

于 2021-04-02T09:33:41.927 回答