Originally published at www.melvinkoh.me . In , we set up our bac-kend with . Now we will set up our front-end to work with our DRF. (We will be using Vue.js, the solution is similar if you are to use it in React.js) Part 1 djangorestframework_jwt Set up Vue.js Make sure you include the following modules: Vue-Axios -> Binder of axios to Vue.$http Vuex (optional) -> State management (Redux in React.js) axios -> Promise based HTTP client jwt_decode -> Decode JWT payload to get expiry timestamp and original issue at timestamp We will be using axios instead of vue-resource as HTTP client, and assume all HTTP requests are handled by . axios Install the requirements npm install --save vue-axios axios vuex jwt-decode Import and Bind to Vue In your main.js, add the following: // main.jsimport axios from 'axios'import VueAxios from 'vue-axios'import jwt_decode from 'jwt-decode'import Vuex from 'vuex' Vue.use(Vuex);Vue.use(VueAxios, axios); // WE WILL ADD THE CODE LATER // YOUR VUE INSTANCE In my case, I define all my methods in Vuex Store actions. You can of course define it in your components tag with slight modification. \<script> Define State and Mutations in Vuex Store I assume you understand how Vuex works. Take a look at its if you are not clear about how it works. official documentation // main.js const store = new Vuex.Store({ state: { jwt: localStorage.getItem('t'), endpoints: { obtainJWT: 'http://0.0.0.0:10000/auth/obtain_token', refreshJWT: 'http://0.0.0.0:10000/auth/refresh_token' } }, mutations: { updateToken(state, newToken){ localStorage.setItem('t', newToken); state.jwt = newToken; }, removeToken(state){ localStorage.removeItem('t'); state.jwt = null; } }, actions: { // WE WILL ADD THIS LATER } }) From the code above, we create a state to store JWT and endpoints as and to manipulate the state of JWT. single source of truth mutations You can see that I use to store our token as well as in state store. This is advisable since Vuex Store will be reinitialize if user refresh the page. You will want to keep your token stored persistently all the time. localStorage Define Actions in Vuex Store // main.js// Add into the placeholder in previous code segment. actions:{ obtainToken(username, password){ const payload = { username: username, password: password } axios.post(this.state.endpoints.obtainJWT, payload) .then((response)=>{ this.commit('updateToken', response.data.token); }) .catch((error)=>{ console.log(error); }) }, refreshToken(){ const payload = { token: this.state.jwt } axios.post(this.state.endpoints.refreshJWT, payload) .then((response)=>{ this.commit('updateToken', response.data.token) }) .catch((error)=>{ console.log(error) }) } inspectToken(){ // WE WILL ADD THIS LATER } } Dispatch Vuex actions Dispatch the actions to obtain JWT and refresh depends on how you design your Vue. Inspect JWT Expire timestamp We would like to inspect our JWT from time to time and to refresh it before it expires. To decode, we use to inspect the _exp_and . jwt_decode orig_iat As mentioned above, is the issuance timestamp of the first token in the token chain. We have set the maximum lifespan to 7 days in our server (Refer to Part 1). orig_iat In the code below, we will check the token against these conditions: 1. IF it is expiring in 30 minutes (1800 second) AND it is not reaching its lifespan (7 days — 30 mins = 630000–1800 = 628200) => REFRESH 2. IF it is expiring in 30 minutes AND it is reaching its lifespan => DO NOT REFRESH 3. IF it has expired => DO NOT REFRESH / PROMPT TO RE-OBTAIN TOKEN (How? Perhaps invoke user to re-login) // Add the following into inspectToken() action above inspectToken(){ const token = this.state.jwt; if(token){ const decoded = jwt_decode(token); const exp = decoded.exp const orig_iat = decode.orig_iat if(exp - (Date.now()/1000) < 1800 && (Date.now()/1000) - orig_iat < 628200){ this.dispatch('refreshToken') } else if (exp -(Date.now()/1000) < 1800){ // DO NOTHING, DO NOT REFRESH } else { // PROMPT USER TO RE-LOGIN, THIS ELSE CLAUSE COVERS THE CONDITION WHERE A TOKEN IS EXPIRED AS WELL } } } It is up to you to design how you would prompt user to re-login, it is frustrating if your page prompts users to login when they are not triggering any HTTP request. I suggest your page only prompts user when they invoke an action the requires authenticated HTTP request. Last Words JWT Authentication is now ready. You should tailor your Vue with the code provided to create a seamless UX. Bonus: When to Inspect Token? I always check the expiration of token whenever the main component is updated or mounted. I include a call to dispatch ‘inspectToken’ in the Vue instance lifecycle hook. Perhaps this is not the best solution, please let me know if you have better idea. Your clap will definitely drive me further. Give me a clap if you like this post. Update at 20 March 2018: An error in the snippet of inspectToken() is rectified. Thank Axel Violon for pointing it out.