【问题标题】:Laravel Sanctum XSRF-TOKEN Cookie not Getting SentLaravel Sanctum XSRF-TOKEN Cookie 未发送
【发布时间】:2021-04-05 05:41:25
【问题描述】:

我正在使用 Laravel 8,并且一直在尝试遵循 SPA authentication 的 sanctum 文档。我已经完成了所需的必要配置的设置。后端服务器使用默认端口(80)在 localhost 上运行,而 SPA 客户端在 localhost:3000 上运行。我正在使用 nuxt 框架为带有 axios 的客户端发出请求。

应向 /sanctum/csrf-cookie 发出初始请求以初始化 CSRF 保护 cookie,这是网络流量显示的内容

第二个请求是应该包含第一个域请求发送的 cookie 的实际请求,但看起来 XSRF-TOKEN 被跳过了。这是网络流量的样子

sanctum.php 配置文件:

<?php
return [
    'stateful' => explode(',', env(
        'SANCTUM_STATEFUL_DOMAINS',
        'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1'
    )),
    'expiration' => null,
    'middleware' => [
        'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class,
        'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class,
    ],
];

cors.php 配置文件:

<?php
return [
    'paths' => ['api/*', 'sanctum/csrf-cookie'],
    'allowed_methods' => ['*'],
    'allowed_origins' => ['*', 'localhost:3000'],
    'allowed_origins_patterns' => [],
    'allowed_headers' => ['*'],
    'exposed_headers' => ['XSRF-TOKEN', 'X-XSRF-TOKEN'],
    'max_age' => 0,
    'supports_credentials' => true,
];

session.php 配置文件

<?php

use Illuminate\Support\Str;

return [
    'driver' => env('SESSION_DRIVER', 'file'),
    'lifetime' => env('SESSION_LIFETIME', 120),
    'expire_on_close' => false,
    'encrypt' => false,
    'files' => storage_path('framework/sessions'),
    'connection' => env('SESSION_CONNECTION', null),
    'table' => 'sessions',
    'store' => env('SESSION_STORE', null),
    'lottery' => [2, 100],
    'cookie' => env(
        'SESSION_COOKIE',
        Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
    ),
    'path' => '/',
    'domain' => env('SESSION_DOMAIN', null),
    'secure' => env('SESSION_SECURE_COOKIE'),
    'http_only' => true,
    'same_site' => 'lax',
];

我在 nuxt.config.js 中设置了这个

export default {
  axios: {
    withCredentials: true,
    baseURL: 'http://localhost/',
  },
}

谁能告诉我为什么 XSRF-TOKEN cookie 没有被发回?

谢谢

【问题讨论】:

  • 目前没有回复,你能分享更多信息吗? cors.php 和 session.php 会有所帮助。

标签: nuxtjs laravel-sanctum


【解决方案1】:

原来问题是由 axios 模块的 nuxt 配置引起的。我只是用简单的“凭据”替换了“withCredentials”字段。

这是现在更新的 nuxt.config.js:

axios: {
    credentials: true,
    baseURL: 'http://localhost/api/',
  },

【讨论】:

    【解决方案2】:

    这是我的 Nuxt/Laravel 8/Sanctum 配置。

    注意我没有在'paths' 中包含'sanctum/csrf-cookie',因为我在sanctum.php 中更改了Sanctum 的前缀。我还在端口 3050 上安装了我的 nuxt 开发服务器,这就是您将在我的配置中看到的内容。更改您的适合(例如 3000)。

    cors.php
    
    'paths' => ['api/*'],
    'allowed_methods' => ['*'],
    'allowed_origins' => [env('ALLOWED_ORIGINS')], 
        .env e.g.: ALLOWED_ORIGINS=http://localhost:3050
    'allowed_origins_patterns' => [],
    'allowed_headers' => ['*'],
    'exposed_headers' => [],
    'max_age' => 0,
    'supports_credentials' => true,
    

    session.php 中的所有内容都是默认设置,但请确保使用正确的 SESSION_DOMAIN 更新您的 .env。

    session.php
    
    'driver' => env('SESSION_DRIVER', 'file'),
    'lifetime' => env('SESSION_LIFETIME', 120),
    'expire_on_close' => false,
    'encrypt' => false,
    'files' => storage_path('framework/sessions'),
    'connection' => env('SESSION_CONNECTION', null),
    'table' => 'sessions',
    'store' => env('SESSION_STORE', null),
    'lottery' => [2, 100],
    'cookie' => env(
        'SESSION_COOKIE',
        Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
    ),
    'path' => '/',
    'domain' => env('SESSION_DOMAIN', null),
        .env e.g.: SESSION_DOMAIN=localhost
    'secure' => env('SESSION_SECURE_COOKIE'),
    'http_only' => true,
    'same_site' => 'lax',
    

    sanctum.php 中的所有内容都是默认设置,请确保在 .env 中输入正确的 SANCTUM_STATEFUL_DOMAIN(示例如下)。我还添加了'prefix' =&gt; 'api' 行。这允许我在 axios 中设置单个 baseURL 并通过 http://localhost:3050/api/csrf-cookie 调用 csrf-cookie 路由。查看更多信息here

    sanctum.php
    
    'stateful' => explode(',', env(
        'SANCTUM_STATEFUL_DOMAINS',
            .env e.g.: SANCTUM_STATEFUL_DOMAINS=localhost:3050
        'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1'
    )),
    'expiration' => null,
    'middleware' => [
        'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class,
        'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class,
    ],
    'prefix' => 'api'
    

    然后在前端,我用 baseURL 设置 axios 并确保 withCredentials 设置为 true

    axios.defaults.withCredentials = true;
    axios.defaults.baseURL = process.env.API_BASE_URL;
        .env e.g.: API_BASE_URL=http://localhost:8000/api
    

    假设您没有进行与上述设置相矛盾的其他更改,这应该可以工作:)

    【讨论】:

      【解决方案3】:

      如果您按照这些指南操作但仍然遇到问题,就像我一样,您可能错过了在 .env 文件中设置 SESSION_DOMAIN

      打开 Laravel 的 .env 文件并添加 SESSION_DOMAIN=.localhost

      还有一点: 如果你因为某种原因无法访问“/csrf-cookie”路由,仍然需要调用“sanctum/csrf-cookie/”,但是Axios在你的请求前添加了/api,那么使用这段代码:

      let myNewInstance = this.$axios.create({
         baseURL: 'http://localhost' //without /api at the end
      });
      
      myNewInstance.get('/sanctum/csrf-cookie');
      

      【讨论】:

        猜你喜欢
        • 2021-07-19
        • 2021-04-24
        • 1970-01-01
        • 2021-12-15
        • 2018-06-13
        • 2013-03-04
        • 2018-02-12
        相关资源
        最近更新 更多