tymondesigns / jwt-auth

🔐 JSON Web Token Authentication for Laravel & Lumen
https://jwt-auth.com
MIT License
11.28k stars 1.54k forks source link

[Guide] [Fix] Middleware for handling authentication and refresh token #2086

Open quevlu opened 3 years ago

quevlu commented 3 years ago

Middleware for handling authentication and refresh token

I have created a middleware for handling authentication and logic of refreshing token.

The process is the following :

1- The request has arrived and the middleware checks if the request has the token, and it's valid after that it continues with the process. 2- The request has arrived, but the token is invalid because it's expired, It refreshes the token and re check again and in the last the new token generated is returned into the response. You must set this token in your next request because is the new token generated. 3- If any of the previous steps can't be executed it throws an exception

Important: The refresh token is only generated when the previous token is expired. The new one will be in the blacklist, and you aren't able to use it again.

`<?php

namespace App\Http\Middleware\v1;

use Closure; use Illuminate\Http\Request; use Illuminate\Validation\UnauthorizedException; use Throwable; use Tymon\JWTAuth\Exceptions\TokenExpiredException; use Tymon\JWTAuth\JWTAuth;

class AuthenticateMiddleware { protected $auth;

public function __construct(JWTAuth $auth)
{
    $this->auth = $auth;
}

public function handle($request, Closure $next)
{
    $token = $this->authenticate($request);

    $response = $next($request);

    return $this->setAuthenticationHeader($response, $token);
}

private function checkToken(Request $request)
{
    if (!$this->auth->parser()->setRequest($request)->hasToken() || !$this->auth->parseToken()->authenticate()) {
        throw new UnauthorizedException;
    }
}

private function authenticate(Request $request)
{
    try {
        $this->checkToken($request);
    } catch (TokenExpiredException $e) {

        try {
            $token = $this->auth->refresh();
            $request = $this->setAuthenticationHeader($request, $token);

            $this->checkToken($request);

            return $token;
        } catch (Throwable $th) {
            throw new UnauthorizedException;
        }
    } catch (Throwable $th) {
        throw new UnauthorizedException;
    }
}

private function setAuthenticationHeader($object, string $token = null)
{
    if ($token) {
        $object->headers->set('Authorization', "Bearer {$token}");
    }

    return $object;
}

} ` If you have a problem with this class, ask me!

Your environment

Q A
Bug? no
New Feature? yes
Framework Laravel / Lumen
Framework version 8.x.y
Package version 1.x.y
PHP version 7.x.y

Steps to reproduce

None

Expected behaviour

None

Actual behaviour

None

mrizkir commented 3 years ago

very nice.

Thank you.