【问题标题】:Laravel - Passport/SPA 401 UnauthorizedLaravel - 护照/SPA 401 未经授权
【发布时间】:2019-02-01 08:42:44
【问题描述】:

我已经注册了 Laravel Passport 文档中提到的 Vue 组件,它们也确实出现在我的应用程序中:

<passport-clients></passport-clients>
<passport-authorized-clients></passport-authorized-clients>
<passport-personal-access-tokens></passport-personal-access-tokens>

但是,它们没有显示任何令牌/客户端,我也无法创建任何令牌/客户端,因为我的应用程序说我“未经授权”:

GET http://spa.test/oauth/personal-access-tokens 401 
GET http://spa.test/oauth/clients 401 (Unauthorized)
GET http://spa.test/oauth/tokens 401 (Unauthorized)
GET http://spa.test/oauth/scopes 401 (Unauthorized)

这是我的AuthServiceProvider.php

public function boot() {
     $this->registerPolicies();
     Passport::routes();
}

我还把这个特性加入了我的app/User.php

use HasApiTokens, Notifiable;

请记住,我使用 Laravel 作为后端,使用 Vue.js 作为前端,这给了我一个 SPA。

这是我的routes/api.php

Route::middleware('auth:api')->group(function () {
    Route::get('/user', function (Request $request) {
        return $request->user();
    });
});

这是我的routes.js

const routes = [
    {
        path: '/api/*',
    },

    /**
     * Handle Authentication
     */
    {
        path: '/',
        alias: '/login',
        name: 'login',
        component: Login,
        beforeEnter: ifNotAuthenticated,
    }
    /**
     * Handle logged in pages
     */
    {
        path: '/dashboard',
        name: 'layout',
        component: MasterLayout,
        beforeEnter: ifAuthenticated,
        children: [{
            path: '/dashboard',
            name: 'dashboard',
            component: Dashboard
        }, {
            path: '/home',
            name: 'home',
            component: Home
        }]
    },
];

更新 1:

我发现问题在于我使用 Passport (auth:api) 进行了身份验证所有的护照路由都使用 Web 中间件来确保您通过身份验证,这是基于会话的身份验证:

更新 2:

请查看我的请求标头:

Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate
Accept-Language: da-DK,da;q=0.9,en-US;q=0.8,en;q=0.7,nb;q=0.6
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImY5OGNiZjBhYmNjZGIyNzk1ZDRhOTllODEwZTQxMzFhMjMwNzhhNzVjYWMzYmM0Y2I2Yzg3NjM3ZDFlMzdkNmI3YzU4YWIzNWM4YmU5MDIxIn0.eyJhdWQiOiIyIiwianRpIjoiZjk4Y2JmMGFiY2NkYjI3OTVkNGE5OWU4MTBlNDEzMWEyMzA3OGE3NWNhYzNiYzRjYjZjODc2MzdkMWUzN2Q2YjdjNThhYjM1YzhiZTkwMjEiLCJpYXQiOjE1MzU0NDU2MzgsIm5iZiI6MTUzNTQ0NTYzOCwiZXhwIjoxNTY2OTgxNjM3LCJzdWIiOiIyIiwic2NvcGVzIjpbXX0.KUSlBt4IQkqYec2TzOTY3QGFxOfuS-SdYpWc26sLDqXpKdRLAqW4XtDOYwzrMtaO51iAuUR1WIGpShaIOZJUhJ_Ya082LVJvuA8tZziAHvjgjReKG_ou6gGhxIWsD8-g88sd0eSyDMfsJBtTs2jrHTJsHQLjFtgwm1RLlSRSkYjO4Tn3fU0dWNUHvcMWVxbuKN_bqC0lpCakjxSQKZe_ep6XpdyFfO84ncsfigVVrfJE3wpJliUfwwv16CpLU0KeNvGhNmKguASCYh9-lWOHPBCMW2S5rF85QgzpTwqYSr5QrIQmqrRKSv6Go545IKN_Hy-xigFV17im-wlVXGOVYgv9C0DJOwCCLOOHB9eMTFO2TGTI5-CLzC8Z9hxHSfMArGGGsTrw6wH45cszvgXH975dk2l1-2rWnVwOMd6-Z2_45Ut0TbomUAfA70OrfSyluxuKKfzNzJ9uobfXB6bGZrIkQMBOPw19N05IkaADAIkip9N99iJ-bF2dCk3GUREmtZPVHo_Yzp0-Ovj0W42eGG5uI_HEhgiuyKdLDWxb92dH_91XhTawhcREx9C1xXQNOUWtT_K2IWaywldfaWy41ZApmd2ZQzhyFxHp28ll1IHKEJRsr88mv4Hjv2hLt5-HeTuL1PW5gaqPZZE5NttpTyK4a2gV7CTtAgm3E_h_Q_Q
Connection: keep-alive
Content-Length: 39
Content-Type: application/json;charset=UTF-8
Cookie: access_token=Bearer%20eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImY5OGNiZjBhYmNjZGIyNzk1ZDRhOTllODEwZTQxMzFhMjMwNzhhNzVjYWMzYmM0Y2I2Yzg3NjM3ZDFlMzdkNmI3YzU4YWIzNWM4YmU5MDIxIn0.eyJhdWQiOiIyIiwianRpIjoiZjk4Y2JmMGFiY2NkYjI3OTVkNGE5OWU4MTBlNDEzMWEyMzA3OGE3NWNhYzNiYzRjYjZjODc2MzdkMWUzN2Q2YjdjNThhYjM1YzhiZTkwMjEiLCJpYXQiOjE1MzU0NDU2MzgsIm5iZiI6MTUzNTQ0NTYzOCwiZXhwIjoxNTY2OTgxNjM3LCJzdWIiOiIyIiwic2NvcGVzIjpbXX0.KUSlBt4IQkqYec2TzOTY3QGFxOfuS-SdYpWc26sLDqXpKdRLAqW4XtDOYwzrMtaO51iAuUR1WIGpShaIOZJUhJ_Ya082LVJvuA8tZziAHvjgjReKG_ou6gGhxIWsD8-g88sd0eSyDMfsJBtTs2jrHTJsHQLjFtgwm1RLlSRSkYjO4Tn3fU0dWNUHvcMWVxbuKN_bqC0lpCakjxSQKZe_ep6XpdyFfO84ncsfigVVrfJE3wpJliUfwwv16CpLU0KeNvGhNmKguASCYh9-lWOHPBCMW2S5rF85QgzpTwqYSr5QrIQmqrRKSv6Go545IKN_Hy-xigFV17im-wlVXGOVYgv9C0DJOwCCLOOHB9eMTFO2TGTI5-CLzC8Z9hxHSfMArGGGsTrw6wH45cszvgXH975dk2l1-2rWnVwOMd6-Z2_45Ut0TbomUAfA70OrfSyluxuKKfzNzJ9uobfXB6bGZrIkQMBOPw19N05IkaADAIkip9N99iJ-bF2dCk3GUREmtZPVHo_Yzp0-Ovj0W42eGG5uI_HEhgiuyKdLDWxb92dH_91XhTawhcREx9C1xXQNOUWtT_K2IWaywldfaWy41ZApmd2ZQzhyFxHp28ll1IHKEJRsr88mv4Hjv2hLt5-HeTuL1PW5gaqPZZE5NttpTyK4a2gV7CTtAgm3E_h_Q_Q; laravel_token=eyJpdiI6IitjQitXXC9iZHd1REtLOWNlZk5qa1d3PT0iLCJ2YWx1ZSI6Im9odjA4SmlqOEY0WndLalpwT29LUGh3R3krXC95eG9sSmtLSHlwYWZlNWFcL1lHbHE2WnRNYWk4UUViVzhUSEpRRzVlWThrdmF4czIrMysrYUZ6UlFzdHVMMDFLMER2VDdUazZDQXBWXC9LMVVZRzdHY2F2RXpFMlRnNmdpaXVXXC9GNFhBK3ZGUm5VdWxKamxsV1RLMDIrTUY1K0JaazBsc2hcL1dHUlBoVXNcL1owalwva3NoVlVzeGc2VElybFwvMFhkN1I0S3g2ZHIralJ4dzIrU3l2aUc2cFwvV1pvQjFRWTRGVXdCdDhwb3UxVXhJeGhpcjNtKzFocjByd25ZQnpzUzVEYUo3dzB0TExqTUVkVCt6ZVFjQ0t4S2dRPT0iLCJtYWMiOiI3NWI0ZjU3OGNhZWQwMTQzYjE1MDBhYzEwNDc4MjBkYzMxZjU5NzI4OGJiMjJmYjQ5NjBhZmMxZTU5ZGZiNmMxIn0%3D; XSRF-TOKEN=eyJpdiI6IkhrQnB1SCs5dWV4OU8zck10djZRbEE9PSIsInZhbHVlIjoieFwvZTJCUFVRZ0haQWNZVjBvUkJ2Q1FTSGtGTHM5SjBXTndOeXBFc2o2Q3pjclRRbjFqeHVpclJOQ3FPTUdKQ2t4M0g4bE5VUXRcL0twdXFNR25IT1NBdz09IiwibWFjIjoiYjI5MzRkNTEwMWZhNWUzNTI5ZTY2OTg5YTYxODQ3MDBkMTU2ZjJjZTE3YzdhZDc2ODMwNjI0NzlmMmQyZTY1NyJ9; laravel_session=eyJpdiI6InY1V3RmeVhvaUd2S2lsRE8wT0tTcHc9PSIsInZhbHVlIjoiQUppMThcL1hka3RXT0NIRWxKNHNUNm5xNjBuaGZSMHpGTXN5czdlWXBqN3dtR2E0UzdQNGFJbk5pS3ZLN1FxZVdnSlVXaE1BaFhVR1lpZnVoek9TMlBBPT0iLCJtYWMiOiIzYmZhYjM5Y2EzYzgwYjdmYTA0OTdjYmYwZGQ2ZThlMDk4YWQ4N2ZiNzRiMjJlZTVkMjM1MjZkYjAyNTZkMTdkIn0%3D
Host: spa.test
Origin: http://spa.test
Referer: http://spa.test/
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36
X-CSRF-TOKEN: v9z5uFoGWPGprc3kJaCMhLpHGbvgQ7usXLwZu11e
X-Requested-With: XMLHttpRequest
X-XSRF-TOKEN: eyJpdiI6IkhrQnB1SCs5dWV4OU8zck10djZRbEE9PSIsInZhbHVlIjoieFwvZTJCUFVRZ0haQWNZVjBvUkJ2Q1FTSGtGTHM5SjBXTndOeXBFc2o2Q3pjclRRbjFqeHVpclJOQ3FPTUdKQ2t4M0g4bE5VUXRcL0twdXFNR25IT1NBdz09IiwibWFjIjoiYjI5MzRkNTEwMWZhNWUzNTI5ZTY2OTg5YTYxODQ3MDBkMTU2ZjJjZTE3YzdhZDc2ODMwNjI0NzlmMmQyZTY1NyJ9

关于我如何仍然使用 Vue 作为前端,Laravel 作为后端并仍然使用 Laravel Passport 来处理令牌的任何想法第三方应用程序?

【问题讨论】:

  • 您是否尝试将您的 laravel 会话 cookie 与请求一起发送?
  • 是的,用这个信息更新了我的 OP。
  • 你使用的是什么版本的 Laravel 和 Passport?
  • @Matpb 两者的最新版本(5.6、7.0)。这是全新安装。

标签: php laravel vue.js single-page-application


【解决方案1】:

不久前我们遇到了同样的问题,但我可以看到我们按照laravel documentationkernel.php 中添加了一个网络中间件:

'web' => [
    // Other middleware...
    // ...
    // This Adds a cookie containing a JWT token for Laravel Passport
    \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],

潜在相关:为了简化我们对后端的请求,我们将 axios 设置为使用 api/ 前缀请求,这意味着我们还必须告诉 Passport 期待这一点。在AuthServiceProvider.php

Passport::routes(null, ['prefix' => 'api/oauth']);

【讨论】:

  • 使用最新的 laravel 版本 + 文档上的护照教程完美工作!
  • 在顶部带有命名空间 use Laravel\Passport\Passport;boot 方法中的 Passport::routes 部分。
【解决方案2】:

大家好,我有同样的未验证问题。 但我的错在于 Postman Header 我设置了 Authorization:'Bearer token'. 它替换为 授权:不记名令牌。好伤心.. 现在它工作了

【讨论】:

    【解决方案3】:

    默认的 oauth 路由分配了 web 和 auth 中间件,因此您必须找到一种方法为它们分配 auth:api 中间件。

    我也更喜欢使用 api/oauth 前缀来保持一致性。

    在您的 AuthServiceProvider 中

    Passport::routes(null, array('prefix' => 'api/oauth', 'middleware'  =>  array('auth:api', 'web', 'auth')));
    

    这将为您提供 api/oauth 前缀并添加 auth:api 中间件,以便您可以通过 Bearer 令牌进行身份验证。

    请记住,您会遇到一些使用 CSRF 令牌的问题

    Passport::ignoreCsrfToken(true);
    

    似乎没有解决。

    您需要传入正确的标头(请参阅 CSRF 保护:https://laravel.com/docs/6.x/passport#consuming-your-api-with-javascript):

    使用这种身份验证方法时,您需要确保请求中包含有效的 CSRF 令牌标头。默认的 Laravel JavaScript 脚手架包含一个 Axios 实例,它会自动使用加密的 XSRF-TOKEN cookie 值在同源请求上发送 X-XSRF-TOKEN 标头。

    【讨论】:

      猜你喜欢
      • 2021-09-24
      • 2018-02-04
      • 2019-12-05
      • 2021-11-30
      • 2017-10-18
      • 1970-01-01
      • 2018-11-03
      • 2018-05-19
      • 2019-10-22
      相关资源
      最近更新 更多