Laravel - Passport/SPA 401 Unauthorized
Asked Answered
A

3

14

I've registered the Vue components as mentioned in the Laravel Passport documentation, and they also do show up in my app:

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

However, they don't show any tokens/clients, and I am not able to create any either, due to my application says I am "unauthorized":

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)

This is my AuthServiceProvider.php

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

I've also included the trait to my app/User.php:

use HasApiTokens, Notifiable;

Remember, I am using Laravel as a backend and Vue.js as a frontend, which gives me an SPA.

This is my routes/api.php:

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

This is my 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
        }]
    },
];

Update 1:

I see that the problem is that I am authenticated using Passport (auth:api) All of the passport routes use web Middleware to make sure you are authenticated, which is a session based authentication:

enter image description here

Update 2:

Please see my request header:

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

Any idea on how I can still use Vue as a frontend, Laravel as a backend and still use Laravel Passport to handle tokens for 3rd party applications?

Albite answered 26/8, 2018 at 17:27 Comment(4)
Have you tried to send your laravel session cookie with the requests?Babism
Yes, updated my OP with this info.Albite
What version of Laravel and Passport are you using?Consecration
@Matpb latest version of both (5.6, 7.0). It's a fresh install.Albite
G
2

It was a little while ago that we went through the same issue, but I can see we followed the laravel documentation to add a web middleware in kernel.php:

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

Potentially relevant: to simplify our requests to the back-end we had axios setup to prefix requests with api/, which meant we also had to tell Passport to expect this. In AuthServiceProvider.php:

Passport::routes(null, ['prefix' => 'api/oauth']);
Garibald answered 30/8, 2018 at 14:7 Comment(2)
Working flawlessly with last laravel version + passport tutorial on doc!Occasion
With namespace use Laravel\Passport\Passport; at the top & the Passport::routes part in the boot method.Lottie
V
2

Hi all i have same issue of Unauthenticated. But my fault is in Postman Header i set Authorization:'Bearer token'. it replace to Authorization:Bearer token.So sad.. Now it working

Vibraculum answered 16/4, 2020 at 6:6 Comment(0)
V
1

The default oauth routes are assigned the web and auth middleware so you have to find a way to assign them the auth:api middleware.

I also prefer to use an api/oauth prefix for consistency.

In your AuthServiceProvider

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

That will give you the api/oauth prefix AND add the auth:api middleware so you can authenticate via Bearer tokens.

Keep in mind you'll encounter some CSRF token issues that using

Passport::ignoreCsrfToken(true);

Doesn't seem to solve.

You'll need to pass in the proper headers (see CSRF Protection under: https://laravel.com/docs/6.x/passport#consuming-your-api-with-javascript):

When using this method of authentication, you will need to ensure a valid CSRF token header is included in your requests. The default Laravel JavaScript scaffolding includes an Axios instance, which will automatically use the encrypted XSRF-TOKEN cookie value to send a X-XSRF-TOKEN header on same-origin requests.

Velour answered 24/9, 2019 at 13:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.