Search code examples
phplaravelvue.jsaxioslaravel-passport

Unauthorized 401 error in laravel 6 passport


I'm trying to use the laravel passport to authenticate users. I followed every step in laravel passport documentation. But it shows error when I access a route that is protected by 'auth:api' middleware. I've searched over the internet but any of the answers are not working so far. Please see the code, and what I've tried so far below.

Tech used

  • Laravel 6
  • Laravel Passport
  • Vue 2
  • Axios

Tried so far:

  • Changed Passport::routes(); to Passport::routes(null, ['prefix' => 'api/oauth', 'middleware' => ['auth:api', 'web', 'auth']]); in AuthServiceProvider. Also tried Passport::routes(null, ['prefix' => 'api/oauth');
  • Tried to run php artisan cache:clear

routes/api.php

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

    Route::get('posts', 'PostController@index')->name('posts');
    Route::post('posts/store', 'PostController@store')->name('posts.store');
    Route::get('posts/{id}/show')->name('posts.show');

    Route::get('users/{id}/show')->name('users.show');
});

Axios

mounted() {
   axios.get('/api/posts')
      .then(res => this.posts = res.data).catch(error => console.log('Unable to fetch posts.'))
}

Error

Headers:

enter image description here

Please let me know if you need some details that is not indicated on my post yet.

Setup

  1. Run composer require laravel/passport:9 for the installation.
  2. Run php artisan migrate for the tables.
  3. Run php artisan passport:install to generate the encryption keys.
  4. Added Laravel\Passport\HasApiTokens trait in User model.
  5. Added Passport::routes(); in AuthServiceProvider.
  6. Changed guard's api driver to passport in config/auth.php.

Full source code:

Click this link


Solution

  • I think you should review your code with the following steps.

    Step 1: User model has to use HasApiTokens

    ...
    class User extends Authenticatable
    {
        use HasApiTokens, Notifiable;
    }
    

    Step 2: Passport::routes method within the boot method of your AuthServiceProvider

    class AuthServiceProvider extends ServiceProvider
    {
    ...
        public function boot()
        {
            $this->registerPolicies();
    
            Passport::routes();
        }
    }
    

    Step 3: In your config/auth.php configuration file, you should set the driver option of the api authentication guard to passport

    'guards' => [
        'api' => [
            'driver' => 'passport',
            'provider' => 'users',
        ],
    ],
    

    Step 4 (Optional): If you want to consume your API from your JavaScript application, you need to manually send an access token to the application and pass it with each request to your application. However, Passport includes a middleware that can handle this for you. All you need to do is add the CreateFreshApiToken middleware to your web middleware group in your app/Http/Kernel.php file:

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

    ! You should ensure that the CreateFreshApiToken middleware is the last middleware listed in your middleware stack.

    Edit (2021/10/17):
    You should try to add the auth middleware to $middlewareGroups of your Kernel.php

    protected $middlewareGroups = [
    ...
      'api' => [
        'throttle:60,1',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'auth:api', //Need to add
      ],
    ];
    

    Edit (2021/10/25):
    I downloaded your code and debug it. When you debug it, you will get the following result:

    enter image description here

    Header JWT is not valid for JSON structure. There seems to be an incompatibility between the Laravel Passport library and your system. You should check your system version (PHP, Laravel, etc). I will continue to investigate. If you have any new information, please let me know

    Edit (2021/11/02):

    Update your laravel/framework dependency to ^6.0 in your composer.json file. If installed, update your laravel/passport dependency to ^9.3.2 in your composer.json file.

    https://laravel.com/docs/6.x/upgrade#updating-dependencies

    According to Laravel 6.x documentation, the version of Laravel Passport is from 9.3.2. Please try this version.