loading...
Cover image for Create API Rest with Laravel 7.X Passport Authentication And Implement Refresh Token (Part 2)

Create API Rest with Laravel 7.X Passport Authentication And Implement Refresh Token (Part 2)

azibom profile image Mohammad Reza ・3 min read

In this part we need to add some routes , some middlewares and some functions to the controller so lets start

Step 1. Change api.php

We need to define three routes like this (we need "/unauthorized" for exception handling)

<?php

use Illuminate\Support\Facades\Route;

Route::post('login', 'UserController@login');
Route::post('register', 'UserController@register');

Route::get('/unauthorized', 'UserController@unauthorized');
Route::group(['middleware' => ['CheckClientCredentials','auth:api']], function() {
    Route::post('logout', 'UserController@logout');
    Route::post('details', 'UserController@details');
});

Step 2. Add functions to UserController.php

You need to add these functions in your controller

...
    public function details() { 
        $user = Auth::user(); 
        return response()->json($user, $this->successStatus); 
    } 

    public function logout(Request $request) {
        $request->user()->token()->revoke();
        return response()->json([
            'message' => 'Successfully logged out'
        ]);
    }

    public function unauthorized() { 
        return response()->json("unauthorized", 401); 
    } 
...

Step 3. Add middleware

First add you middleware

php artisan make:middleware CheckClientCredentials

Then you should change CheckClientCredentials.php it like this

<?php

namespace App\Http\Middleware;

use Closure;
use Laminas\Diactoros\StreamFactory;
use Laminas\Diactoros\ResponseFactory;
use Laminas\Diactoros\UploadedFileFactory;
use Laminas\Diactoros\ServerRequestFactory;
use Laravel\Passport\Http\Middleware\CheckCredentials;
use League\OAuth2\Server\Exception\OAuthServerException;
use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;

class CheckClientCredentials extends CheckCredentials
{
    public function handle($request, Closure $next, ...$scopes)
    {
        $psr = (new PsrHttpFactory(
            new ServerRequestFactory,
            new StreamFactory,
            new UploadedFileFactory,
            new ResponseFactory
        ))->createRequest($request);

        try {
            $psr = $this->server->validateAuthenticatedRequest($psr);
        } catch (OAuthServerException $e) {
            return response()->json($e->getPayload(), $e->getHttpStatusCode()); 
        }

        return $next($request);
    }

    protected function validateCredentials($token) {}
    protected function validateScopes($token, $scopes) {}
}

After that you need to change Authenticate.php (for exception handling)

<?php

namespace App\Http\Middleware;

use Illuminate\Auth\Middleware\Authenticate as Middleware;

class Authenticate extends Middleware
{
    /**
     * Get the path the user should be redirected to when they are not authenticated.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return string|null
     */
    protected function redirectTo($request)
    {
        if (! $request->expectsJson()) {
            return '/api/unauthorized';
        }
    }
}

Step 4. Change Kernel.php

We need to change some things in Kernel and add CheckClientCredentials middleware to $routeMiddleware and add it also in $middlewarePriority because we need to show CheckClientCredentials first!
Add CheckClientCredentials in $routeMiddleware

    protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
        'CheckClientCredentials' => \App\Http\Middleware\CheckClientCredentials::class #changed
    ];

Add CheckClientCredentials in $middlewarePriority (you don't have this variable in kernel class and you should overwrite it)

    protected $middlewarePriority = [
        \App\Http\Middleware\CheckForMaintenanceMode::class, #changed
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests::class,
        \Illuminate\Routing\Middleware\ThrottleRequests::class,
        \Illuminate\Session\Middleware\AuthenticateSession::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
        \Illuminate\Auth\Middleware\Authorize::class
    ];

Step 5. Now you can test it

You can test new urls and see the result
details
Alt Text
logout
Alt Text

In next part we try to implement the refresh token

Create API Rest with Laravel 7.X Passport Authentication And Implement Refresh Token (Part 3)

Posted on by:

azibom profile

Mohammad Reza

@azibom

azibom ... bom ... bom

Discussion

markdown guide
 

Hello, how can i use getTokenAndRefreshToken with a social login ?
with social i haven't password, can i ask for a refreshtoken without a password?