Laravel Sanctum XSRF-TOKEN Cookie 未发送
Laravel Sanctum XSRF-TOKEN Cookie not Getting Sent
我正在使用 Laravel 8,并且我一直在尝试遵循 SPA authentication 的密室文档。我已经完成设置所需的必要配置。后端服务器在具有默认端口 (80) 的本地主机上为 运行,而 SPA 客户端在 localhost:3000 上为 运行。我正在为带有 axios 的客户端使用 nuxt 框架来发出请求。
应向 /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 没有被发回吗?
谢谢
这是我的 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' => '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
假设您没有进行与上述设置相矛盾的其他更改,这应该有效:)
原来问题是由axios模块的nuxt配置引起的。我只是用 'credentials'.
替换了字段 'withCredentials'
这是更新后的 nuxt.config.js:
axios: {
credentials: true,
baseURL: 'http://localhost/api/',
},
如果您按照这些指南进行操作但仍然遇到问题,就像我一样,您可能错过了 .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');
我正在使用 Laravel 8,并且我一直在尝试遵循 SPA authentication 的密室文档。我已经完成设置所需的必要配置。后端服务器在具有默认端口 (80) 的本地主机上为 运行,而 SPA 客户端在 localhost:3000 上为 运行。我正在为带有 axios 的客户端使用 nuxt 框架来发出请求。
应向 /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 没有被发回吗?
谢谢
这是我的 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
.
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' => '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
假设您没有进行与上述设置相矛盾的其他更改,这应该有效:)
原来问题是由axios模块的nuxt配置引起的。我只是用 'credentials'.
替换了字段 'withCredentials'这是更新后的 nuxt.config.js:
axios: {
credentials: true,
baseURL: 'http://localhost/api/',
},
如果您按照这些指南进行操作但仍然遇到问题,就像我一样,您可能错过了 .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');