【问题标题】:vue-cli frontend not setting CSRF cookie from Sanctumvue-cli 前端未从 Sanctum 设置 CSRF cookie
【发布时间】:2020-08-20 16:36:32
【问题描述】:

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

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

/sanctum/csrf-cookie 的 GET 看起来不错,但是,它似乎并没有真正设置 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 的响应标头:

devtools 中未列出任何 cookie:

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

【问题讨论】:

    标签: vue.js cookies axios csrf-token laravel-sanctum


    【解决方案1】:

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

    长答案:Laravel Sanctum 使用 VerifyCsrfToken 中间件发送和验证 CSRF 令牌,uses session config values when adding the cookie to the response

    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
    

    Cookies on the same host ARE NOT distinguishable by ports。因为我在 cookie 域中指定了端口,所以浏览器将 cookie 标记为具有无效域。删除端口就可以了。

    【讨论】:

    • 来到这里是为了说这是我问题的答案,以防它对未来的人有所帮助。极具误导性,因为在 sanctum 的文档中它说“如果您通过包含端口 (127.0.0.1:8000) 的 URL 访问您的应用程序,您应该确保在域中包含端口号。”在laravel.com/docs/8.x/sanctum上的一个大信息框旁边
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2021-09-26
      • 2020-09-20
      • 2021-06-22
      • 1970-01-01
      • 1970-01-01
      • 2015-05-22
      • 2020-07-02
      • 2017-05-05
      • 2020-12-05
      相关资源
      最近更新 更多