Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Basic strategy for delegate refresh token to get new JWT

I have been doing pretty well implementing Angular SPA and JWT, but I always have a hard time with delegating for a new token.

My basic strategy has been:

  1. In auth interceptor get Auth Error = > Delegate with refresh token, replace JWT, else logout

Which did not work because multiple Async calls would fire and one would get the delegate function, but then the refresh token would have been used for the second one and that one will fail, then the user would get logged out.

  1. Before anything else: Check token expiration, if expired => delegate with refresh token, replace jwt, else logout

Which had a similar issue where the first call would notice it was expired, and go get the new token, but since it is Async, the rest of the calls would fire and fail etc.

What is the basic strategy here. I feel like the very first thing the app should do is check the JWT and delegate for a new one if it's a bad token, but in that case it should no be asynchronous. Do I just not delete the refresh token on use?

Any help would be great, I feel like this is the last major hole in my understanding. Thanks!

like image 582
Z2VvZ3Vp Avatar asked Dec 11 '15 23:12

Z2VvZ3Vp


1 Answers

Try using Witold Szczerba's "http interceptor".

In a nutshell the first failed http call triggers and event and subsequent calls get pushed into an array. Upon the event firing you have a chance to do some logic and then replay the failed calls.

That said you probably should just do a token rotation before needing to actually use the refresh token. For example consider this code which could be added to this function

.config(function($httpProvider) {
    $httpProvider.interceptors.push(function(moment, $rootScope, $q, httpBuffer) {
        return {
            request: function (config) {
                if ($rootScope.authToken) {
                    config.headers["Authentication"] = 'Bearer ' + $rootScope.authToken;
                    var payload = angular.fromJson(atob($rootScope.authToken.split('.')[1]));
                    var utcNow = moment.utc().valueOf();
                    // 3600000 ms = 1 hr
                    if(utcNow > payload.iat + 3600000){
                        $rootScope.$broadcast('auth:rotateToken', $rootScope.authToken);
                    }
                }

                return config;
            },
            //responseError: ...see Witold's code...
    });
})
like image 126
Cory Silva Avatar answered Oct 21 '22 02:10

Cory Silva