我使用 nextauth 进行身份验证,但是当我使用凭据提供程序登录时,它不会调用/调用会话回调。当我控制台日志时,我看到
userModified
对象和来自 JWT 回调的令牌对象,但会话回调中没有任何内容是 console.log,并且会话不会被创建和返回,也不会保存到数据库中。
但是,当我使用谷歌登录时,会话对象被调用:
import NextAuth, { type NextAuthOptions } from "next-auth";
import GoogleProvider from "next-auth/providers/google";
import CredentialsProvider from "next-auth/providers/credentials";
import bcryptjs from "bcryptjs";
import { PrismaClient } from "@prisma/client";
import EmailProvider from "next-auth/providers/email";
// Prisma adapter for NextAuth, optional and can be removed
import { PrismaAdapter } from "@next-auth/prisma-adapter";
import { env } from "../../../env/server.mjs";
import { prisma } from "../../../server/db/client";
export const authOptions: NextAuthOptions = {
// Include user.id on session
callbacks: {
async session({ session, user , token }) {
console.log('session ',session)
console.log('user ', user)
if (session.user) {
session.user.id = user.id;
}
return {
...session,
user
};
},
async jwt({token , user}) {
console.log('user is ',user)
console.log('token is ', token)
return token
}
},
// Configure one or more authentication providers
adapter: PrismaAdapter(prisma),
providers: [
GoogleProvider({
clientId: env.GOOGLE_CLIENT_ID,
clientSecret: env.GOOGLE_CLIENT_SECRET,
}),
CredentialsProvider({
name : "credentials",
credentials : {
email : {label : 'Email', name : 'email', type : 'email'},
password : {label : 'Password', name: 'password',type : 'password'}
},
async authorize(credentials) {
if(!credentials){
return null
}
const { email, password } = credentials
if(!email || !password) {
return null
}
const userExists = await prisma.user.findUnique({
where : {
email : credentials.email
}
})
if (!userExists || !userExists.hashedPassword) {
return null
}
const isPasswordValid = await bcryptjs.compare(password,userExists.hashedPassword)
if(!isPasswordValid) {
return null
}
const user = {
id : userExists.id,
email : userExists.email,
isRegistered : userExists.isRegistered
}
console.log('user modified', user)
return user
}
})
// ...add more providers here
],
session:{ strategy: "database", }
};
export default NextAuth(authOptions);
这是 schema.prisma 中的会话:
model Session {
id String @id @default(cuid())
sessionToken String @unique
userId String
expires DateTime
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
我希望用户能够通过
CredentialsProvider
使用电子邮件和密码登录。这涉及验证所提供的凭据,包括电子邮件和密码。
authorize
中的CredentialsProvider
函数将验证用户凭据并返回代表经过身份验证的用户的对象,其中应包括:
id : userExists.id,
email : userExists.email,
isRegistered : userExists.isRegistered
使用凭据成功登录后,我希望调用 jwt 回调,我在 console.log 中看到了这一情况。此回调记录令牌和用户数据,并应返回 JWT 令牌数据。
这没有发生:
然后我期望调用会话回调。此回调根据从授权函数接收到的用户数据添加 user.id 属性来修改会话。它应该返回带有用户属性的修改后的会话对象。然后更新数据库中的Session表
我遇到了同样的问题,添加密钥为我解决了这个问题。
export default NextAuth({ secret: process.env.NEXTAUTH_SECRET, providers: [...] })
我面临的问题是我忘记添加会话提供程序。
在我添加的layout.tsx中。
<SessionProvider>
{children}
</SessionProvider>