-
-
Save chz/f0a25fd1b12b64daaf86ef871b804fd9 to your computer and use it in GitHub Desktop.
Vue/Nuxt JWT Authentication Implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // reusable aliases for mutations | |
| export const AUTH_MUTATIONS = { | |
| SET_USER: 'SET_USER', | |
| SET_PAYLOAD: 'SET_PAYLOAD', | |
| LOGOUT: 'LOGOUT', | |
| } | |
| export const state = () => ({ | |
| access_token: null, // JWT access token | |
| refresh_token: null, // JWT refresh token | |
| id: null, // user id | |
| email_address: null, // user email address | |
| }) | |
| export const mutations = { | |
| // store the logged in user in the state | |
| [AUTH_MUTATIONS.SET_USER] (state, { id, email_address }) { | |
| state.id = id | |
| state.email_address = email_address | |
| }, | |
| // store new or updated token fields in the state | |
| [AUTH_MUTATIONS.SET_PAYLOAD] (state, { access_token, refresh_token = null }) { | |
| state.access_token = access_token | |
| if (refresh_token) { | |
| state.refresh_token = refresh_token | |
| } | |
| }, | |
| // clear our the state, essentially logging out the user | |
| [AUTH_MUTATIONS.LOGOUT] (state) { | |
| state.id = null | |
| state.email_address = null | |
| state.access_token = null | |
| state.refresh_token = null | |
| }, | |
| } | |
| export const actions = { | |
| async login ({ commit, dispatch }, { email_address, password }) { | |
| // make an API call to login the user with an email address and password | |
| const { data: { data: { user, payload } } } = await this.$axios.post('/api/auth/login', { email_address, password }) | |
| // commit the user and tokens to the state | |
| commit(AUTH_MUTATIONS.SET_USER, user) | |
| commit(AUTH_MUTATIONS.SET_PAYLOAD, payload) | |
| }, | |
| async register ({ commit }, { email_addr, password }) { | |
| // make an API call to register the user | |
| const { data: { data: { user, payload } } } = await this.$axios.post('/api/auth/register', { email_address, password }) | |
| // commit the user and tokens to the state | |
| commit(AUTH_MUTATIONS.SET_USER, user) | |
| commit(AUTH_MUTATIONS.SET_PAYLOAD, payload) | |
| }, | |
| // given the current refresh token, refresh the user's access token to prevent expiry | |
| async refresh ({ commit, state }) { | |
| const { refresh_token } = state | |
| // make an API call using the refresh token to generate a new access token | |
| const { data: { data: { payload } } } = await this.$axios.post('/api/auth/refresh', { refresh_token }) | |
| commit(AUTH_MUTATIONS.SET_PAYLOAD, payload) | |
| }, | |
| // logout the user | |
| logout ({ commit, state }) { | |
| commit(AUTH_MUTATIONS.LOGOUT) | |
| }, | |
| } | |
| export const getters = { | |
| // determine if the user is authenticated based on the presence of the access token | |
| isAuthenticated: (state) => { | |
| return state.access_token && state.access_token !== '' | |
| }, | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import createPersistedState from 'vuex-persistedstate' | |
| import * as Cookies from 'js-cookie' | |
| import cookie from 'cookie' | |
| // access the store, http request and environment from the Nuxt context | |
| // https://nuxtjs.org/api/context/ | |
| export default ({ store, req, isDev }) => { | |
| createPersistedState({ | |
| key: 'authentication-cookie', // choose any name for your cookie | |
| paths: [ | |
| // persist the access_token and refresh_token values from the "auth" store module | |
| 'auth.access_token', | |
| 'auth.refresh_token', | |
| ], | |
| storage: { | |
| // if on the browser, parse the cookies using js-cookie otherwise parse from the raw http request | |
| getItem: key => process.client ? Cookies.getJSON(key) : cookie.parse(req.headers.cookie || '')[key], | |
| // js-cookie can handle setting both client-side and server-side cookies with one method | |
| // use isDev to determine if the cookies is accessible via https only (i.e. localhost likely won't be using https) | |
| setItem: (key, value) => Cookies.set(key, value, { expires: 14, secure: !isDev }), | |
| // also allow js-cookie to handle removing cookies | |
| removeItem: key => Cookies.remove(key) | |
| } | |
| })(store) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment