Laravel / angularjs JWT marker update

I am implementing JWT authentication in an angular / laravel application and I have a problem updating the token.

Here is the relevant code:

PHP: a laravel-jwt listener that listens for the tymon.jwt.expired event:

/** * Fired when the token has expired * @param \Exception $e * @return \Illuminate\Http\JsonResponse */ public function expired($e) { $token = \JWTAuth::parseToken(); Config::package('tymon/jwt-auth', 'jwt'); $ttl = Config::get('jwt::refresh_ttl'); $iat = Carbon::createFromTimestamp($token->getPayload()->get('iat')); $now = Carbon::now(); // if renew ttl is expired too, return 401, otherwise let // the application generate a new token to frontend if ($iat->diffInMinutes($now) >= $ttl) { unset($iat, $now, $ttl); return response_failure( Lang::get('errors.api.auth.expired'), Config::get('status.error.unauthorized') ); } unset($iat, $now, $ttl); } 

PHP: filter "after":

 /* |-------------------------------------------------------------------------- | JWT-Auth token-refresh Filter |-------------------------------------------------------------------------- | | The RefreshToken filter update the response headers by returning an | updated authentication token. | */ Route::filter('RefreshToken', function($route, $request, $response) { $token = JWTAuth::parseToken(); try { $token->toUser(); } catch (TokenExpiredException $e) { Config::package('tymon/jwt-auth', 'jwt'); $ttl = Config::get('jwt::refresh_ttl'); $iat = \Carbon\Carbon::createFromTimestamp($token->getPayload()->get('iat')); $now = \Carbon\Carbon::now(); if ($iat->diffInMinutes($now) < $ttl) { $response->headers->set('Authorization', 'Bearer ' . $token->refresh()); } } }); 

PHP: Authenticated Route Filters:

 Route::group(['before' => 'jwt-auth', 'after' => 'RefreshToken'], function () { ... }); 

JS: interceptor that updates localstorage

 'use strict'; angular.module('App') .factory('ResponseInterceptor', ['SessionService', 'jwtHelper', '$location', '$q', function (SessionService, jwtHelper, $location, $q) { return { response: response }; // called for http codes up to 300 function response(response) { var token = response.headers('Authorization'); if ('undefined' !== typeof token && null !== token) { SessionService.setToken(token.split(' ')[1]); } return response; } }]); 

This works well, except for one problem (workflow):

  • the token expires, but can still be updated.
  • angular send http request with expired token to server
  • laravel catches the request and updates the response headers with a new token
  • laravel blacklist previous token

The problem is that if any request is sent from angular during the extension delay, all thoses requests are rejected from the server, because the token is invalid (blacklisted).

Am I doing something wrong? Can someone point me in the right direction?

What I would like to get is to set the ttl of the token after about 5 minutes and allow the user to update the token during navigation.

+5
source share
3 answers

It really was a mistake in the library, fixed now read here for more information

+1
source

Perhaps you are using asynchronous requests? Then you are not sure if you are sending the latest token.

In this case, you should not use the update method after each request.

0
source

I had the same problem. When the token is updated, the last token will be blacklisted. however, you need this token if another asynchronous call is launched before the last answer. Thus, the solution may be a blacklist of the last token with a delay. And you can do this by setting JWT_BLACKLIST_GRACE_PERIOD to the JWT_BLACKLIST_GRACE_PERIOD configuration file. ♥♥♥

0
source

Source: https://habr.com/ru/post/1215526/


All Articles