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?
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With