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

Posted

技术标签:

【中文标题】使用 Passport 进行 Laravel API 身份验证导致 401(未经授权)【英文标题】:Laravel API Authentication using Passport results in 401 (Unauthorized) 【发布时间】:2017-08-18 07:27:09 【问题描述】:

按照 Laravel 上有关 API 路由的 Passport authentication 的文档,我目前在使用 axois 从 api 获取数据时遇到了一些问题。

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

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

当我运行以下 sn-p 来测试所有内容时,就会出现问题:

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

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

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

Cookie:laravel_token=eyJpdiI6ImJ5RG1KRk....

X-XSRF-TOKEN:eyJpdiI6IlVRRHhxSXp2VDVy...

我做错了吗?

【问题讨论】:

我有同样的错误,但下面的答案并没有解决它... 您尝试过github.com/laravel/passport/issues/47#issuecomment-242808444 的修复吗? 这为我解决了这个问题:github.com/laravel/passport/issues/795#issuecomment-411708604 【参考方案1】:

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

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

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

【讨论】:

感谢您抽出宝贵时间回答! :-) 我现在添加了 auth:api 中间件,但它仍然显示为未经授权。 你的服务器在 nginx 上吗? 我在 Vagrant / Homestead (NginX/1.11.9) 上运行 Laravel 您可能还可以从这个帖子中尝试一些事情:github.com/laravel/passport/issues/47 你是一个了不起的人! :) 我整天都在这,ryanhungate 在该页面上的解决方案解决了它。不确定它是否会在未来增加一些其他问题,但目前我很高兴它可以工作! :) 谢谢!【参考方案2】:

试试这个命令,它对我很有用。

php artisan config:cache

【讨论】:

只是给尝试所有选项的人的消息,请小心。 php artisan config:cache 缓存您的配置,这意味着您将更难找到错误。使用php artisan cache:clear 再次清除它。【参考方案3】:

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

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

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

然后给出例子:

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

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

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

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

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

【讨论】:

【参考方案4】:

CreateFreshApiToken 必须在最后一行。

'web' => [
    // Other middleware...
    \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],

【讨论】:

【参考方案5】:

我尝试了以下代码。将以下代码粘贴到项目根文件夹中的 .htaccess 文件中。

RewriteEngine On
RewriteCond %HTTP:Authorization ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]

【讨论】:

以上是关于使用 Passport 进行 Laravel API 身份验证导致 401(未经授权)的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5.7 在播种机中使用 Passport 进行测试

使用 Passport 和 Laravel 进行身份验证时返回访问令牌和用户

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

php 使用Passport进行Laravel REST API身份验证:https://www.cloudways.com/blog/rest-api-laravel-passport-authen

使用 VueX 和 Laravel Passport 进行身份验证

使用 Nuxt 前端实现 Laravel 7 Passport 身份验证