Skip to content

Instantly share code, notes, and snippets.

@kirkbushell
Created January 7, 2016 22:41
Show Gist options
  • Star 17 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save kirkbushell/6b60a44c0949d08feb46 to your computer and use it in GitHub Desktop.
Save kirkbushell/6b60a44c0949d08feb46 to your computer and use it in GitHub Desktop.
Handling JWT, Vue JS and token refreshes
import Unauthorised from './Unauthorised'
export default function() {
return {
response: function(response) {
switch (response.status) {
case 401: return Unauthorised.handle();
}
return response;
}
}
};
import Vue from "vue"
import JWT from "../../components/authentication/JWT"
export default {
handle: function(response) {
var retry = function() {
JWT.setToken(response.data.token);
return this.retry(response.request).then(function() {
return response;
});
}.bind(this);
// Refresh JWT, then retry previous request if successful, and catch any errors (auth fail of some kind)
return Vue.http.get('/auth/refresh')
.then(retry)
.catch(this.redirect);
},
/**
* Retries the request initially made by the app before an auth error was thrown.
*
* @param request
* @return Promise
*/
retry: function(request) {
var method = request.method.toLowerCase();
return Vue.http[method](request.url, request.params);
},
redirect: function() {
window.location.href = '/auth';
}
};
@nivv
Copy link

nivv commented May 9, 2016

Just found this example, it works nicely, except for one thing. In my component I set data on the VM like below:

fetchArticles: function() {
            this.$http.get({url: '/api/v2/articles?number=5000'}).then( (response) => {
                this.$set('articles', response.data.data);
                this.$set('appReady', true);
            }, (response) => {
                // error callback
            });
        }

The retry method seems to ignore the then function. Is there a way to run the then "method" as well?

@kirkbushell
Copy link
Author

@nivv tbh I'm not really sure. This a bit old now, but I do remember having a number of issues (about 2 days worth of time) to get it working in the end. Was a stack of trial and error. Sorry I can't be more help.

@nivv
Copy link

nivv commented May 10, 2016

@kirkbushell, no worries! Feels a bit silly to be able to do the refresh of the token, and then retry the request but then not being able to use the data in the response.

@nivv
Copy link

nivv commented May 10, 2016

@kirkbushell

I solved it using vuex and a watcher on the component.

    /**
     * Retries the request initially made by the app before an auth error was thrown.
     *
     * @param request
     * @return Promise
     */
    retry: function(request) {
        var method = request.method.toLowerCase();
        console.log('old token, retrying')
            return Vue.http[method](request.url, request.params).then( (response) => {
                response['done'] = true;
                store.dispatch('SET_FAILED_REQUEST_DATA', response);
            }, (response) => {
                this.redirect();
            });
    },

In my component

    watch: {
        'failedRequestData': function(val) {
            if(val.done === true) {
                this.$set('articles', this.failedRequestData.data.data);
                this.$set('appReady', true);
                store.dispatch('SET_FAILED_REQUEST_DATA', {done: false});
            }
        }
    },

@rajeshwar-fissionhq
Copy link

What if i have more no.of components? Let's say i have 100 components, in this case, we can't write watchers in all the components right? So what would be the best solution for it, to pass the data to the previous call?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment