Skip to content

Instantly share code, notes, and snippets.

@wooooodward
Created November 6, 2019 17:16
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save wooooodward/afe610206fa47560fdd0d94d2209247e to your computer and use it in GitHub Desktop.
Save wooooodward/afe610206fa47560fdd0d94d2209247e to your computer and use it in GitHub Desktop.
Axios plugin example with request interceptor that adds JWT token to the auth header and 401 response interceptor to refresh token
import Vue from 'vue'
import axios from 'axios'
import store from '../store'
import { TokenService } from '../services/storage.service'
// Full config: https://github.com/axios/axios#request-config
let config = {
baseURL:
process.env.baseURL ||
process.env.apiUrl ||
'http://localhost:8000/api/v1/',
timeout: 1000, // 1 second
withCredentials: true, // check cross-site Access-Control
xsrfCookieName: 'csrftoken',
xsrfHeaderName: 'X-CSRFToken'
}
const _axios = axios.create(config)
_axios.interceptors.request.use(
config => {
// Add or remove auth header before request is sent
const token = TokenService.getToken()
if (token) {
config.headers.common['Authorization'] = 'JWT ' + token
} else {
delete config.headers.common['Authorization']
}
return config
},
error => {
return Promise.reject(error)
}
)
_axios.interceptors.response.use(
response => {
return response
},
async error => {
// Intercept 401 response and retry
const token = TokenService.getToken()
if (error.response.status === 401 && token) {
if (error.response.config.url.includes('/token/refresh/')) {
store.dispatch('userModule/logout')
throw error
} else {
try {
await store.dispatch('userModule/reLogin')
return _axios.request({
method: error.response.config.method,
url: error.response.config.url,
data: error.response.config.data
})
} catch (e) {
store.dispatch('userModule/logout') // refresh failed
}
}
}
return Promise.reject(error)
}
)
Plugin.install = function(Vue) {
Vue.axios = _axios
window.axios = _axios
Object.defineProperties(Vue.prototype, {
axios: {
get() {
return _axios
}
},
$axios: {
get() {
return _axios
}
}
})
}
Vue.use(Plugin)
export default Plugin
const ACCESS_TOKEN_KEY = 'access'
const REFRESH_TOKEN_KEY = 'refresh'
const TokenService = {
/**
* Manage the how Access Tokens are being stored and retrieved from storage.
*
* Current implementation stores to localStorage. Local Storage should always be
* accessed through this instance.
**/
getToken() {
return localStorage.getItem(ACCESS_TOKEN_KEY)
},
saveToken(accessToken) {
localStorage.setItem(ACCESS_TOKEN_KEY, accessToken)
},
removeToken() {
localStorage.removeItem(ACCESS_TOKEN_KEY)
},
getRefreshToken() {
return localStorage.getItem(REFRESH_TOKEN_KEY)
},
saveRefreshToken(refreshToken) {
localStorage.setItem(REFRESH_TOKEN_KEY, refreshToken)
},
removeRefreshToken() {
localStorage.removeItem(REFRESH_TOKEN_KEY)
}
}
export { TokenService }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment