Last active
September 7, 2022 18:26
-
-
Save TheDutchCoder/c900ac16ca389779169a91a4f51a7599 to your computer and use it in GitHub Desktop.
This file contains 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
```ts | |
/** | |
* 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