Skip to content

Instantly share code, notes, and snippets.

@TheDutchCoder
Last active September 7, 2022 18:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TheDutchCoder/c900ac16ca389779169a91a4f51a7599 to your computer and use it in GitHub Desktop.
Save TheDutchCoder/c900ac16ca389779169a91a4f51a7599 to your computer and use it in GitHub Desktop.
/**
* This plugin runs on the server and checks for the user's access token and
* refresh token cookies.
*
* If one of them is missing, the user will be logged out and cookies will be
* removed as a precaution.
*
* If both tokens are still valid, we get the user's account and log them in.
*
* If the access token has expired, we use the refresh token to get a new access
* token, as wel as the account for the user and log them in.
*/
/* eslint-disable import/no-named-as-default-member */
// eslint-disable-next-line import/default
import jwt from 'jsonwebtoken'
import Cookie from 'cookie-universal'
export default defineNuxtPlugin(async (nuxtApp) => {
const config = useRuntimeConfig()
if (nuxtApp.ssrContext?.event) {
const { setUser, removeUser } = useAuth()
const cookie = Cookie(nuxtApp.ssrContext.event.req, nuxtApp.ssrContext?.event.res)
const accessToken = cookie.get(config.cookieAccessToken)
const refreshToken = cookie.get(config.cookieRefreshToken)
const fifteenMinutes = 15 * 60 * 1000
// Check if the refresh token is still valid, otherwise log the user out and
// clean up the cookies.
try {
jwt.verify(refreshToken, useRuntimeConfig().jwtSecret)
} catch (e) {
removeUser()
cookie.remove(config.cookieRefreshToken, {
path: '/',
httpOnly: true,
sameSite: 'none',
secure: true,
})
cookie.remove(config.cookieAccessToken, {
path: '/',
httpOnly: true,
sameSite: 'none',
secure: true,
})
return
}
// Check if the access token is still valid. If it is, get the user's
// account and store it. If it's not, refresh the access token and log the
// user in. When an issue occurs, log the user out and clean up the cookies.
try {
jwt.verify(accessToken, useRuntimeConfig().jwtSecret)
// Decode the token to get the user's id.
const decodedAccessToken = jwt.decode(accessToken)
// Make sure the token contains a user id.
if (typeof decodedAccessToken !== 'string' && decodedAccessToken?.id) {
// Get the user's account.
const data = await GqlGetAccount({ id: decodedAccessToken.id })
setUser(data.getAccount)
return
}
} catch (e) {
const data = await GqlDoRefreshToken({ input: { refreshToken } })
const accessToken = data.refreshToken?.accessToken
const decodedAccessToken = jwt.decode(accessToken)
// Create a new cookie for the access token.
if (decodedAccessToken) {
cookie.set(config.cookieAccessToken, accessToken, {
path: '/',
httpOnly: true,
sameSite: 'none',
secure: true,
expires: new Date(Date.now() + fifteenMinutes),
})
}
// Make sure the token contains a user id.
if (typeof decodedAccessToken !== 'string' && decodedAccessToken?.id) {
// Get the user's account.
const data = await GqlGetAccount({ id: decodedAccessToken.id })
setUser(data.getAccount)
return
}
// Things went wrong, so remove the user and clean up the cookies.
removeUser()
cookie.remove(config.cookieRefreshToken, {
path: '/',
httpOnly: true,
sameSite: 'none',
secure: true,
})
cookie.remove(config.cookieAccessToken, {
path: '/',
httpOnly: true,
sameSite: 'none',
secure: true,
})
}
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment