我将 next.js 与 next-auth 一起使用。我使用 AzureAD 提供商。现在我想将用户数据存储在我自己的数据库中,因为 Azure AD 的性能非常糟糕。当用户第一次登录时,我想将名称和图像存储在数据库中。为此,我添加了用于 next-auth 的 prisma 适配器,并将函数
profile
添加到了处理用户返回数据的 azure 提供程序。我在那里交出该用户的 AzureProfile ID。但prisma总是会忽略ID字段并让数据库创建ID。
其他字段都没有问题。它们存储在数据库中,正如我在返回的对象中定义它们一样。只有ID是个问题。
有没有办法手动定义数据库中新创建的User的ID?
这些是我的下一个AuthOptions:
import { type AuthOptions } from 'next-auth'
import type { User } from '@prisma/client'
import { originalPrisma } from 'lib/prisma'
// ...
export const authOptions: AuthOptions = {
adapter: PrismaAdapter(originalPrisma),
session: {
strategy: 'jwt',
},
providers: [
AzureADProvider({
clientId: process.env.AZURE_AD_CLIENT_ID!,
clientSecret: process.env.AZURE_AD_CLIENT_SECRET!,
tenantId: process.env.AZURE_AD_TENANT_ID!,
authorization: { params: { scope } },
idToken: true,
async profile(profile, tokens) {
const profileData: Pick<
User,
'id' | 'name' | 'email' | 'emailVerified' | 'image'
> = {
id: profile.oid!,
name: profile.name,
email: profile.email,
emailVerified: profile.email_verified || null,
image: null,
}
// ...
return profileData
},
}),
]
}
终于想通了这个问题。
// @ts-ignore
const customAdapter: Adapter = (p: PrismaClient) => {
return {
...PrismaAdapter(p),
createUser: async (data: any) => {
console.log("default createUser", data);
data.id = data.oid;
//remove oid from data
delete data.oid;
console.log("custom createUser", data);
return p.user.create({ data });
},
};
};
使用自定义适配器并 确保配置文件具有 oid,以便可以将其传递给自定义适配器
adapter: customAdapter(prisma),
providers: [
AzureAD({
async profile(profile, tokens) {
return {
id: profile.oid,
oid: profile.oid,
name: profile.name,
email: profile.preferred_username, }
;}
})
]