Laravel sanctum 获得 401 未授权
Posted
技术标签:
【中文标题】Laravel sanctum 获得 401 未授权【英文标题】:Getting 401 unauthorized for Laravel sanctum 【发布时间】:2020-08-08 19:18:18 【问题描述】:我正在使用 Laravel Sanctum 和 Vuejs SPA。两者都位于同一个***域
Laravel backend : app.demo.localhost
Vue SPA : app-spa.demo.localhost
当使用 axios 从 VueJS SPA 调用并且成功设置 XSRF-TOKEN 时,登录和注销(端点)工作正常,但是当我调用其他 api 端点时,它给了我 401 未授权。
在 axios 中这是被设置的
axios.defaults.withCredentials = true;
我有以下配置
在 Laravel .env 中
SESSION_DRIVER=cookie
SESSION_DOMAIN=.demo.localhost
SANCTUM_STATEFUL_DOMAINS=app-spa.demo.localhost
在 Routes/Api.php 中
Route::middleware('auth:sanctum')->get('api/user', function (Request $request)
return $request->user();
);
在 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,
有人可以帮帮我吗?
【问题讨论】:
你上面没有显示,你在app/Http/Kernel.php
中启用了sanctum中间件吗? laravel.com/docs/7.x/sanctum#spa-authentication
你解决了这个问题吗?
我在生产服务器上遇到了同样的问题,使用 react 和 axios。 O 开发服务器工作正常
有人解决这个问题吗?我正在使用自定义警卫成功登录。但是即使设置了 xsrf 令牌等,后续请求也会失败......
面临同样的问题。如果有人找到它,请提供答案。
【参考方案1】:
如果您使用的是 php artisan serve,请将端口号添加到 SANCTUM_STATEFUL_DOMAINS。所以如果你的端口号是 8000:
SESSION_DRIVER=cookie
SESSION_DOMAIN=.demo.localhost
SANCTUM_STATEFUL_DOMAINS=app-spa.demo.localhost:8000
您的 SANCTUM_STATEFUL_DOMAINS 必须与您浏览器中的网址匹配。端口号不应在 SESSION_DOMAIN 上。
【讨论】:
我在 SESSION_DOMAIN 设置中添加了端口号,这使它返回 401 - 我删除了端口号,它立即工作 - 谢谢!【参考方案2】:对于任何与本地主机打交道的人:
SESSION_DRIVER=cookie
SESSION_DOMAIN=localhost
SANCTUM_STATEFUL_DOMAINS=localhost:8080(port number you use)
【讨论】:
【参考方案3】:我刚刚遇到了同样的问题。我按照官方文档配置了所有选项,但是无法获得授权。
那我用routes/web.php代替routes/api.php,这样可以很好的使用sanctum中间件。
现在问题似乎很明显了,Axios withCredentials 可能需要以正确的方式放置。
const http = axios.create(
baseURL: API_URL,
withCredentials: true
)
也许行不通。所以我加了withCredentials: true
like
http.get('/api/whoami', withCredentials: true)
.then(res =>
console.log(res.data)
)
然后就可以了。
但是很奇怪的是现在正常了,不管我清除浏览器缓存、cookies还是Laravel的各种缓存,都没有以前的情况
【讨论】:
人...这是唯一对我有用的解决方案!谢谢。【参考方案4】:以下是我在设置 Laravel sanctum 时遵循的 8 个步骤,检查你是否遗漏了什么
第一步 composer require laravel/sanctum
第二步 php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider
Step3 php artisan migrate
(如果您正在使用水疗,可以忽略此)
Step4 从 app/http/kernel.php \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
取消注释此行
Step5在config/cors.php中更新'supports_credentials' => true,
Step6 在 .env 文件中更新 SESSION_DRIVER=cookie
并添加 SESSION_DOMAIN=localhost
的新行(即使您使用像 8080 这样的任何端口,只需在 session_domain 中提及 localhost)
Step7 在 config/sanctum.php 中添加您的客户端域以及端口(如果是本地),如下所示,在我的情况下,对于 vue CLI,它通常是 localhost:8080
&对于 nuxt 它的 @987654329 @ ,代码如下
'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) : ''
))),
大多数情况下,如果您的状态(步骤 7)设置不正确,您将获得 401 未授权,或者它会尝试将您重定向到主页以及 cors 策略错误
Step8在解决sanctum/csrf-cookie
承诺之前不要忘记await
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);
,
【讨论】:
【参考方案5】:我的问题是....(没有仔细阅读)
如果您的 SPA 需要使用私有/在线广播频道进行身份验证,您应该将 Broadcast::routes 方法调用放在 您的 routes/api.php 文件e中:
【讨论】:
【参考方案6】:您好,我找到了解决方案。
我的 SPA 是在 3000 端口上运行的 Vue v3。 我的后端也在 80 端口上工作。 (laravel 8.1)
像这样在 config/sanctum.php 中创建有状态域
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s',
'localhost:3000',
env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : ''
))),
仅在其上添加一个正确的域,这对我来说很神奇。我之前写过所有可能的端口变体,这让我抓狂并且花费了几天几夜。
【讨论】:
【参考方案7】:我的问题是我在错误的地方设置了域。
我以为是一个域数组,在config/sanctum.php
,但不是,需要放在字符串中:
好的:
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1,myownlocaldomain.test,myownlocaldomain.test:8080', <-------- OK
env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : ''
))),
不好:
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : '',
'myownlocaldomain.test', <----- BAD
'myownlocaldomain.test:8080', <---- BAD
))),
我希望我能把几天的工作留给别人...
【讨论】:
以上是关于Laravel sanctum 获得 401 未授权的主要内容,如果未能解决你的问题,请参考以下文章
使用 nuxtjs 登录 laravel sanctum 后出现 401(未验证)错误
如何使用 Laravel Sanctum 和 React 修复 401 Unauthorized 错误?
带有 Vuejs 的 Laravel 7.x Sanctum (SPA) 总是返回 401 Unauthorized
Laravel Sanctum 和使用 Pusher.js 进行广播(401、419 错误)