Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel Passport invalid scope(s) provided exception

  • Laravel Passport version 8.0.0
  • Laravel version: 6.2

I defined scopes of my API using the Passport::tokensCan method in the boot method of AuthServiceProvider.php file:

Passport::routes();

Passport::tokensCan([
    'view-posts' => 'View posts',
    'create-posts' => 'Create posts'
]);

Added the following middleware to the $routeMiddleware property of app/Http/Kernel.php file:

protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    /*
    . . .
    */
    'scopes' => \Laravel\Passport\Http\Middleware\CheckScopes::class,
    'scope' => \Laravel\Passport\Http\Middleware\CheckForAnyScope::class,
];

Then, I protected an API route in routes/api.php:

Route::post('/posts', [
    'uses' => 'PostController@store',
    'middleware' => ['auth:api', 'scope:create-posts']
]);

In a client app, my authorization route is (routes/web.php):

Route::middleware(['auth'])->group(function () {
    Route::get('/auth/blogger', 'BloggerAuthController@redirect');
    Route::get('/auth/blogger/callback', 'BloggerAuthController@callback');
});

And BloggerAuthController controller is like so:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use GuzzleHttp\Client as Guzzle;

class BloggerAuthController extends Controller
{
    protected $client;

    public function __construct(Guzzle $client)
    {
        $this->client = $client;
    }

    public function redirect()
    {
        $query = http_build_query([
            'client_id' => '3',
            'redirect_uri' => 'http://localhost:8001/auth/blogger/callback',
            'response_type' => 'code',
            'scope' => 'view-posts'
        ]);

        return redirect('http://localhost:8000/oauth/authorize?' . $query);
    }

    public function callback(Request $request)
    {
        $response = $this->client->post('http://localhost:8000/oauth/token', [
            'form_params' => [
                'grant_type' => 'authorization_code',
                'client_id' => '3',
                'client_secret' => 'gG5HcVn1JlGhzO0RfgTfWuqP8IVro1Qhu9g2q0Dq',
                'redirect_uri' => 'http://localhost:8001/auth/blogger/callback',
                'code' => $request->code
            ]
        ]);

        $response = json_decode($response->getBody());

        $request->user()->token()->delete();

        $request->user()->token()->create([
            'access_token' => $response->access_token
        ]);

        return redirect('/home');
    }
}

When I (POST) request to /api/posts from my client app, I get an exception:

{
    "message": "Invalid scope(s) provided.",
    "exception": "Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException",
    "file": "C:\\Users\\nbayramberdiyev\\Desktop\\fresh\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Exceptions\\Handler.php",
    "line": 206,
    /*
    . . .
    */
}

But the expected result would be:

{
    "message": "Unauthenticated."
}

with status 401.

Why is this happening? Did I miss anything in docs?

like image 885
N'Bayramberdiyev Avatar asked Nov 12 '19 16:11

N'Bayramberdiyev


1 Answers

You just need to overwrite MissingScopeException exception to return whatever message you want and still scope Middleware in your route files

in Exception folder in Handler file in the render function

if ($exception instanceof MissingScopeException && $request->wantsJson()){
            return response()->json([
                'error' => 'Unauthenticated',
            ], 403);
        }
like image 169
Mohammed Alama Avatar answered Nov 07 '22 19:11

Mohammed Alama