Skip to content

Instantly share code, notes, and snippets.

@Stormix
Last active May 30, 2020 10:41
Show Gist options
  • Save Stormix/6135a61b4b801e4a586836a68de4658c to your computer and use it in GitHub Desktop.
Save Stormix/6135a61b4b801e4a586836a68de4658c to your computer and use it in GitHub Desktop.
Laravel SPA token mismatch 419
import axios from 'axios'
import createAuthRefreshInterceptor from 'axios-auth-refresh'
const getCSRFToken = () => {
const token: HTMLMetaElement | null = document.head.querySelector(
'meta[name="csrf-token"]'
)
return token?.content
}
axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'
axios.defaults.withCredentials = true
const token: string | undefined = getCSRFToken()
if (token) {
axios.defaults.headers.common['X-CSRF-TOKEN'] = token
} else {
console.error(
'CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token'
)
}
// The following code adds an interceptor that renews the CSRF token whenever
// the app recieves a token mismatch error
const refreshCSRFToken = () => {
return new Promise((resolve, reject): void => {
console.log('Token expired, fetching a new one')
axios
.get('/')
.then(({ data }) => {
const wrapper = document.createElement('div')
wrapper.innerHTML = data
return wrapper
.querySelector('meta[name=csrf-token]')
?.getAttribute('content')
})
.then((token) => {
document
.querySelector('meta[name=csrf-token]')
?.setAttribute('content', token || '')
resolve()
})
.catch(() => reject())
})
}
createAuthRefreshInterceptor(axios, refreshCSRFToken, {
statusCodes: [419],
})
// Using a second interceptor to inject the newly fetched CSRF token to all requests
axios.interceptors.request.use((request) => {
request.headers['X-CSRF-TOKEN'] = getCSRFToken()
return request
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment