We are doing OTP auth in our website. So in order to get authorized, a visitor enter his phone number in input and we send him a OPT number and he again enters the sent opt, then if it matches, we send him his account credendials (token, userID) if exists or we create new and we want to save that credentails in session useing next-auth.
This is where i got so far:
export default NextAuth({
providers: [
CredentialsProvider({
credentials: {
phoneNumber: { label: 'PhoneNumber', type: 'text' },
code: { label: 'Code', type: 'text' },
type: { label: 'Type', type: 'text' },
},
async authorize(credentials, req) {
const user_needs = await requests.auth.signInEnterOtp(
credentials.phoneNumber,
credentials.code,
credentials.type
)
return user_needs.ok ? true : null
},
}),
],
callbacks: {
async session({ session, user, token }) {
return session
},
},
secret: process.env.JWT_SECRET,
})
I need to save the user_needs
in session but how can i pass it throuh authorize
to session
?
I tried returning the user_need
in authorize
but it was not passed to session
callback.
Eventually i figured it out like this:
async authorize(credentials, req) {
const res = fetchUserInfo(credentials.opt)
if(res.ok) return {user: res.data} // res.data contains whatever received from DB call => fetchUserInfo(credentials.opt)
return null
},
callbacks: {
async jwt({ token, user }) {
// the user present here gets the same data as received from DB call made above -> fetchUserInfo(credentials.opt)
return { ...token, ...user }
},
async session({ session, user, token }) {
// user param present in the session(function) does not recive all the data from DB call -> fetchUserInfo(credentials.opt)
return token
},
},
I myself understood callback cycle better now:
authorize --> jwt --> session
jwt
callback(cb) accepts the user
object that authorize
cb returns.
By default jwt
retuns the token
and things return from there is then available in the token
object of session
cb
async authorize(credentials, req) {
return { user: { role: 'ADMIN' } }
},
async jwt({ token, user }) {
return { ...token, role: user.role }
},
async session({ session, token }) {
return { ...session, token.role }
}
But when i use Providers
, i won't have authorize
cb, so to get user's role i need to query db in jwt
cb but this callback runs a lot and i don't know what is the better option