3

I am having my application back-end implementation in Lumen which gives a JWT token every time a user logs in. The front end I am using Angular to save the token in the local storage and also I am adding it to all the headers in the subsequent requests. To check the expiry of the token and refresh by creating a request I am using https://github.com/auth0/angular-jwt

I am adding the token refresh code in the config of the app but this method is never called when I make any other requests here is the code which I tried.

app.config(function Config($httpProvider, jwtInterceptorProvider) {


  jwtInterceptorProvider.tokenGetter = function(jwtHelper, $http,$localStorage) {

    if ($localStorage.currentUser) {
    var token = $localStorage.currentUser.token;
    if (jwtHelper.isTokenExpired(token)) {

      return $http({
        url: 'http://backend.mywebsite.com/token',
        method: 'GET'
      }).then(function(response) {
        var token = response.token;
      $localStorage.currentUser.token = token;
      $http.defaults.headers.common.Authorization = 'Bearer ' +   $localStorage.currentUser.token;
        return token;
      });
    } else {
      return token;
    }
  }
}
$httpProvider.interceptors.push('jwtInterceptor');
});

I would like to know how to configure this functionality so that whenever the token expires it is automatically refeshed and set in the http headers?

1 Answer 1

5

Points you should consider

  1. You shouldn't change the default headers inside the tokenGetter function.
  2. If your token is expired, you can't call the token endpoint.

You have two options, you can use Refresh tokens and make a post request to a delegation endpoint that makes use of the refresh tokens to obtain a new(not-expired) token.

OR

You can update the JWT with a delegation endpoint and request for a new access token just before the token expires. If the token has expired and there is no refresh_token, you can't really do anything.

A refresh token is a special kind of JWT that is used to authenticate a user without them needing to re-authenticate. It carries the information necessary to obtain a new access token.

In other words, whenever an access token is required to access a specific resource, a client may use a refresh token to get a new access token issued by the authentication server. Common use cases like yours include getting new access tokens after old ones have expired, or getting access to a new resource for the first time. Refresh tokens can also expire but are rather long-lived.

A sample code example for using a refresh token to obtain a new token after a token has expired can be found below:

angular.module('app', ['angular-jwt'])
    .config(function Config($httpProvider, jwtInterceptorProvider) {
        jwtInterceptorProvider.tokenGetter = function(jwtHelper, $http) {
            var jwt = localStorage.getItem('JWT');
            var refreshToken = localStorage.getItem('refresh_token');

            if (jwtHelper.isTokenExpired(jwt)) {
                // This is a promise of a JWT id_token
                return $http({
                    url: '/delegation',
                    // This will not send the JWT for this call
                    skipAuthorization: true,
                    method: 'POST',
                    refresh_token : refreshToken
                }).then(function(response) {
                    localStorage.setItem('JWT', response.data.jwt);
                    return jwt;
                });
            } else {
                return jwt;
            }
        }
        $httpProvider.interceptors.push('jwtInterceptor');
    })

If you want more information about refresh tokens and how they work, you can check out this article.

Sign up to request clarification or add additional context in comments.

4 Comments

This is more or less similar to what I have done, but this doesn't trigger the request when the token expires.
In your implementation, I can't see any refresh token and in your sample code, this line is missing $httpProvider.interceptors.push('jwtInterceptor');
I already had that line to register the interceptor, I have updated the code. What is happening is that interceptor is only called when I login, that is the only time the token is checked. for further requests the token is not checked and thus I get a 401
Ok I got this working, and the issue was in the angular-jwt library as it was passing the old token in the headers. After referring to this discussion and the possible fix I was able to get it working

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.