Skip to content

Instantly share code, notes, and snippets.

@vanling
Last active July 27, 2023 07:05
Show Gist options
  • Save vanling/b10ebe14ee90ff249bea28bf94abb745 to your computer and use it in GitHub Desktop.
Save vanling/b10ebe14ee90ff249bea28bf94abb745 to your computer and use it in GitHub Desktop.
import CredentialsProvider from 'next-auth/providers/credentials'
import { NuxtAuthHandler } from '#auth'
export default NuxtAuthHandler({
// secret needed to run nuxt-auth in production mode (used to encrypt data)
secret: useRuntimeConfig().authSecret,
providers: [
CredentialsProvider.default({
name: 'Directus',
credentials: {
email: { label: 'Email', type: 'text' },
password: { label: 'Password', type: 'password' },
},
async authorize(credentials, req) {
try {
const userTokens = await $fetch(
`https://${useRuntimeConfig().public.directusUrl}/auth/login`,
{
method: 'POST',
body: {
email: credentials.email,
password: credentials.password,
},
headers: {
'Content-Type': 'application/json',
},
}
)
const userDetails = await $fetch(
`https://${useRuntimeConfig().public.directusUrl}/users/me`,
{
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${userTokens?.data?.access_token}`,
},
}
)
if (
!userTokens ||
!userTokens.data ||
!userDetails ||
!userDetails.data
) {
throw createError({
statusCode: 500,
statusMessage: 'Nuxt auth failed',
})
}
const user = {
id: userDetails.data.id,
email: userDetails.data.email,
firstName: userDetails.data.first_name,
name:
userDetails.data.first_name + ' ' + userDetails.data.last_name,
image: userDetails.data.avatar,
lastName: userDetails.data.last_name,
role: userDetails.data.role,
status: userDetails.data.status,
accessToken: userTokens.data.access_token,
accessTokenExpires: Date.now() + userTokens.data.expires,
refreshToken: userTokens.data.refresh_token,
}
return user
} catch (error) {
console.warn('Error logging in', error)
return null
}
},
}),
],
session: {
strategy: 'jwt',
},
callbacks: {
async signIn({ user }) {
// Do your checks here like status active and/or role checking
// const allowedRoles = [
// 'bf86376e-e657-400f-8009-93cd733cc7a5', //use role a
// 'bf86376e-e657-400f-8009-93cd733cc7a5', //use role b
// ]
// if (allowedRoles.includes(user.role) && user.status === 'active') {
// return true
// } else {
// return false
// }
return true
},
async jwt({ token, user, account }) {
if (account && user) {
// omit token info
let { accessToken, accessTokenExpires, refreshToken, ...filtered } =
user
token = {
...token,
user: filtered,
...{
access_token: accessToken,
access_token_expires: accessTokenExpires - 1000 * 60,
refresh_token: refreshToken,
},
}
}
if (
token.access_token_expires &&
Date.now() > token.access_token_expires
) {
console.log('refresh token please')
const refresh = await $fetch(
`https://${useRuntimeConfig().public.directusUrl}/auth/refresh`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: {
refresh_token: token.refresh_token,
mode: 'json',
},
}
)
if (!refresh || !refresh.data) {
console.warn('No refreshed tokens')
throw refresh
}
token = {
...token,
...{
access_token: refresh.data.access_token,
access_token_expires: Date.now() + refresh.data.expires - 1000 * 60,
refresh_token: refresh.data.refresh_token,
},
}
}
// console.log(token)
return token
},
async session({ session, token, user, profile }) {
session.accessToken = token.access_token
session.user = {
...session.user,
id: token.sub,
role: token.user.role,
access_token: token.access_token,
}
return session
},
},
})
@kadlinobit
Copy link

@vanling I tried couple of solutions after switching to Nuxt 3, but there was always something wrong or missing... Then I put my personal project to sleep and thought I would wait for the (long-ago) announced official nuxt-auth module. Which still didn't come any closer to be released. 😄

But this nuxt-directus module by Becem sounds like something that could solve it for me as well, I have to try it out.

Thanks so much for the info! Cheers!

@quroom
Copy link

quroom commented Jul 27, 2023

@vanling
Don't you have any problem when open browser with token expires?
I am struggling update cookie problem :(
sidebase/nuxt-auth#498
I guess the code, there is no problem.. but cookie was not updated..
Doesn't it happend to you?

If it doesn't happend, could I know which nuxt-auth and next-auth version you use?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment