为 Laravel sanctum 获取 401 未授权

MOH*_*EEB 10 vue.js axios laravel-7 laravel-sanctum

我正在将 Laravel Sanctum 与 Vuejs SPA 一起使用。两者都驻留在同一个顶级域中

Laravel backend : app.demo.localhost
Vue SPA : app-spa.demo.localhost
Run Code Online (Sandbox Code Playgroud)

当使用 axios 从 VueJS SPA 调用时登录和注销(端点)工作正常,并且 XSRF-TOKEN 已成功设置,但是当我调用其他 api 端点时,它给了我 401 未经授权。

在 axios 中,这是设置

axios.defaults.withCredentials = true;
Run Code Online (Sandbox Code Playgroud)

我有以下配置

在 Laravel .env 中

SESSION_DRIVER=cookie
SESSION_DOMAIN=.demo.localhost
SANCTUM_STATEFUL_DOMAINS=app-spa.demo.localhost
Run Code Online (Sandbox Code Playgroud)

在路由/Api.php

Route::middleware('auth:sanctum')->get('api/user', function (Request $request) {
   return $request->user();
});
Run Code Online (Sandbox Code Playgroud)

在 cors.php

'paths' => ['api/*', 'sanctum/csrf-cookie', 'login', 'logout'],

'allowed_methods' => ['*'],

'allowed_origins' => ['*'],

'allowed_origins_patterns' => [],

'allowed_headers' => ['*'],

'exposed_headers' => [],

'max_age' => 0,

'supports_credentials' => true,
Run Code Online (Sandbox Code Playgroud)

有人可以帮我吗?

Sco*_*cot 24

如果您使用 php artisan serve,请将端口号添加到 SANCTUM_STATEFUL_DOMAINS。因此,如果您的端口号是 8000:

SESSION_DRIVER=cookie
SESSION_DOMAIN=.demo.localhost
SANCTUM_STATEFUL_DOMAINS=app-spa.demo.localhost:8000
Run Code Online (Sandbox Code Playgroud)

您的 SANCTUM_STATEFUL_DOMAINS 必须与浏览器中的 url 匹配。端口号不应在 SESSION_DOMAIN 上。


kun*_*put 20

以下是我在设置 Laravel sainttum 时遵循的 8 个步骤,检查您是否遗漏了什么

步骤1 composer require laravel/sanctum

第2步 php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider

Step3 php artisan migrate(如果你用的是spa可以忽略这一步)

Step4 取消 app/http/kernel.php 中这一行的注释\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,

Step5在config/cors.php中更新'supports_credentials' => true,

步骤 6在 .env 文件中更新SESSION_DRIVER=cookie并添加新行SESSION_DOMAIN=localhost(即使您使用 8080 等任何端口,只需在 session_domain 中提及localhost )

步骤7 在 config/sanctum.php 中添加您的客户端域以及有状态的端口(如果是本地),如下所示,在我的 vue CLI 中,通常是localhost:8080& 对于 nuxt it localhost:3000,代码如下

    'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
        '%s%s',
        'localhost,localhost:8000,localhost:8080,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
        env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : ''
    ))),
Run Code Online (Sandbox Code Playgroud)

大多数情况下,如果您的有状态(第 7 步)设置不正确,您将收到 401 未经授权的消息,或者它会尝试将您重定向到主页以及 cors 策略错误

Step8不要忘记await直到sanctum/csrf-cookie承诺得到解决

    async login() {
      await axios.get("http://localhost:8000/sanctum/csrf-cookie");

      await axios.post("http://localhost:8000/login", {
        email: "kunal@gmail.com",
        password: "password",
      });

      let response = await axios.get("http://localhost:8000/api/user");
      console.log(response.data);
    },

Run Code Online (Sandbox Code Playgroud)


小智 9

对于任何与本地主机打交道的人:

SESSION_DRIVER=cookie    
SESSION_DOMAIN=localhost    
SANCTUM_STATEFUL_DOMAINS=localhost:8080(port number you use)
Run Code Online (Sandbox Code Playgroud)


Nul*_*ll_ 1

我刚刚遇到了同样的问题。我按照官方文档配置了所有选项,但无法获得授权。

\n\n

然后我使用routes/web.php而不是routes/api.php,这样我就可以很好地使用sanctum中间件。

\n\n

现在问题似乎很明显\xef\xbc\x8cAxios withCredentials 可能需要以正确的方式放置。

\n\n
const http = axios.create({\n    baseURL: API_URL,\n    withCredentials: true\n})\n
Run Code Online (Sandbox Code Playgroud)\n\n

也许不起作用。所以我添加{withCredentials: true}喜欢

\n\n
http.get('/api/whoami', {withCredentials: true})\n  .then(res => {\n                console.log(res.data)\n            })\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后就可以了。

\n\n

但很奇怪的是现在正常了,无论我清除浏览器缓存、cookies还是Laravel的各种缓存,都没有以前的情况了

\n