使用 Passport 的 Laravel API 身份验证导致 401(未经授权)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43015063/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 15:39:12  来源:igfitidea点击:

Laravel API Authentication using Passport results in 401 (Unauthorized)

phplaravelapiauthenticationlaravel-passport

提问by palan

Following the documentation on Laravel regarding Passport authenticationfor the API route, i'm currently having some problems when using axois to fetch data from the api.

根据 Laravel 关于API 路由的Passport 身份验证的文档,我目前在使用 axois 从 api 获取数据时遇到了一些问题。

So far I have installed Passport through Composer, added the hasApiTokens trait, added a call to Passport::routes within the boot method of AuthServiceProvider and set the driver option of api authentication guard to 'passport'.

到目前为止,我已经通过 Composer 安装了 Passport,添加了 hasApiTokens 特征,在 AuthServiceProvider 的 boot 方法中添加了对 Passport::routes 的调用,并将 api 身份验证防护的驱动程序选项设置为“passport”。

Since I would like the user to consume the API through Javascript from a Vue based SPA after login, I have added CreateFreshApiToken to the web middleware group.

由于我希望用户在登录后通过基于 Vue 的 SPA 的 Javascript 使用 API,因此我将 CreateFreshApiToken 添加到 Web 中间件组。

The problem occurs when I run the following snippet to test everything out:

当我运行以下代码段来测试所有内容时会出现问题:

axios.get('api/users').then( function(response) { console.log(response.data); }); 

The result is a 'Failed to load resource: the server responded with a status of 401 (Unauthorized)' response.

结果是“加载资源失败:服务器响应状态为 401(未授权)”响应。

I have checked the headers from the request sent with axois and the headers contain both

我已经检查了使用 axois 发送的请求的标头,标头包含两者

Cookie:laravel_token=eyJpdiI6ImJ5RG1KRk....

Cookie:laravel_token=eyJpdiI6ImJ5RG1KRk....

and

X-XSRF-TOKEN:eyJpdiI6IlVRRHhxSXp2VDVy...

X-XSRF-TOKEN:eyJpdiI6IlVRRHhxSXp2VDVy...

Am i doing anything wrong?

我做错了什么吗?

回答by jeremykenedy

Try adding the auth middleware to the api group of your Kernel.php

尝试将 auth 中间件添加到您的 api 组中 Kernel.php

    'api' => [
        'throttle:60,1',
        'bindings',
        'auth:api',
    ],

https://github.com/jeremykenedy/laravel-passport/blob/master/app/Http/Kernel.php

https://github.com/jeremykenedy/laravel-passport/blob/master/app/Http/Kernel.php

回答by Shawn K

I was able to resolve this error that dozens or hundreds of people report online, but none of the existing solutions worked for me, except for the following.
using Laravel 5.8, following docs to set up Passport.

我能够解决数十人或数百人在线报告的此错误,但除了以下解决方案之外,现有的解决方案均不适合我。
使用 Laravel 5.8,按照文档设置 Passport。

In my case, although I was including the csrf token in a meta tag, it was not being picked up as the Passport documentation states that laravel will by default. from the docs (https://laravel.com/docs/5.8/passport#consuming-your-api-with-javascript):

就我而言,虽然我在元标记中包含了 csrf 令牌,但它并没有被选中,因为 Passport 文档指出 laravel 默认会这样做。来自文档(https://laravel.com/docs/5.8/passport#sumption-your-api-with-javascript):

" the default Laravel JavaScript scaffolding instructs Axios to always send the X-CSRF-TOKEN and X-Requested-With headers. "

" 默认的 Laravel JavaScript 脚手架指示 Axios 始终发送 X-CSRF-TOKEN 和 X-Requested-With 标头。"

and then the example is provided:

然后提供示例:

// In your application layout...
<meta name="csrf-token" content="{{ csrf_token() }}">

// Laravel's JavaScript scaffolding...
window.axios.defaults.headers.common = {
    'X-Requested-With': 'XMLHttpRequest',
};

Well that would be great if it worked that way by default as the docs state, but in my case I had to explicitly set the axios default to include the contents of said csrf-token meta tag before making the axios request. like this:

好吧,如果它在文档状态下默认以这种方式工作,那就太好了,但在我的情况下,我必须在发出 axios 请求之前明确设置 axios 默认值以包含所述 csrf-token 元标记的内容。像这样:

window.axios.defaults.headers.common = {
                        'X-Requested-With': 'XMLHttpRequest',
                        'X-CSRF-TOKEN' : document.querySelector('meta[name="csrf-token"]').getAttribute('content')
                };

In my case, this was the only thing that allowed me to get past the 401 unauthorized error, which seems to indicate either:
A) something in my project's configuration has altered the default behavior of axios requests by not setting them automatically include the csrf-token based on the meta tag if present or
B) the docs are inaccurate on this one point, and in the present version of Laravel and Passport that is not the default behavior as stated.

就我而言,这是唯一能让我克服 401 未授权错误的方法,这似乎表明:
A) 我的项目配置中的某些内容改变了 axios 请求的默认行为,因为它们没有自动设置,包括 csrf-基于元标记的令牌(如果存在)或
B)文档在这一点上不准确,并且在 Laravel 和 Passport 的当前版本中,这不是所述的默认行为。

回答by Yudistira Ashadi

Try this command, it's work for me like a charm.

试试这个命令,它对我来说就像一个魅力。

php artisan config:cache