Mostly when building mobile apps, we want to show the signin page only once and then leave the user logged in forever. For those cases, it makes sense to have a refreshToken. A refreshToken lets us get a new id_token or JWT anytime we want.
Warning: This means that if the
refreshTokengets compromised, unless we revoke that token, somebody would be able to get a new JWT forever. This is why we only suggest to use Refresh Tokens in Mobile Applications, not in Web Applications.
In order to be able to get the refresh token, all we need to do is add the offline_access scope when calling the signin or signup. Optionally, you can set the device parameter.
auth.signin({
authParams: {
scope: 'openid offline_access',
// The following is optional
device: 'Chrome browser'
}
});We recommend using angular-storage to store the refresh token. You can learn how to store information with it in this other guide.
Now, you want to always send a not expired JWT to the server when calling it. For that, you'll use angular-jwt. You can learn how to install and configure the library in this other guide.
The only difference with the example on the angular-jwt guide is that now you'll configure the library to get a new JWT if the current one is expired:
angular.module('myApp', ['auth0', 'angular-jwt'])
.config(function($httpProvider, jwtInterceptorProvider) {
var refreshingToken = null;
jwtInterceptorProvider.tokenGetter = function(store, $http, jwtHelper) {
var token = store.get('token');
var refreshToken = store.get('refreshToken');
if (token) {
if (!jwtHelper.isTokenExpired(token)) {
return store.get('token');
} else {
if (refreshingToken === null) {
refreshingToken = auth.refreshIdToken(refreshToken).then(function(idToken) {
store.set('token', idToken);
return idToken;
}).finally(function() {
refreshingToken = null;
});
}
return refreshingToken;
}
}
}
$httpProvider.interceptors.push('jwtInterceptor');
});Once the page is refreshed, you want the user to stay logged in. For that, if the JWT is expired, you'll use the refreshToken to get a new one:
angular.module('myApp', ['auth0', 'angular-jwt', 'angular-storage'])
.run(function($rootScope, auth, store, jwtHelper, $location) {
var refreshingToken = null;
$rootScope.$on('$locationChangeStart', function() {
var token = store.get('token');
var refreshToken = store.get('refreshToken');
if (token) {
if (!jwtHelper.isTokenExpired(token)) {
if (!auth.isAuthenticated) {
auth.authenticate(store.get('profile'), token);
}
} else {
if (refreshToken) {
if (refreshingToken === null) {
refreshingToken = auth.refreshIdToken(refreshToken).then(function(idToken) {
store.set('token', idToken);
auth.authenticate(store.get('profile'), idToken);
}).finally(function() {
refreshingToken = null;
});
}
return refreshingToken;
} else {
$location.path('/login');
}
}
}
});
})That's it :). Now, you can check out some of our examples.