使用 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