-
-
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 | |
}, | |
}, | |
}) |
@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!
@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?
@kadlinobit Hi, thanks.
To be honest, I've used this in production before but replaced it all with https://github.com/becem-gharbi/nuxt-directus. There was just too much going on with authenticating for Directus SDK requests etc.
It has been a while but I think it came down to a composable that wrapped all the directus.items() calls and when that failed it tried to refresh token.. and when that failed again the composable triggered an modal/notification telling the user to login again.
It was getting more and more complex and then i found the nuxt-directus by Becem.. fixed al my issues. Login directly, login with providers.. uses the standard Directus SDK but replaced axios for $fetch.