我正在将 next-auth 与两个提供商(Prisma 适配器和 MongoDB)一起使用。在某些时候,图书馆开始表现奇怪 - 授权时,它从不同的帐户登录我。当使用不同的提供商、不同的浏览器甚至不同的设备时,问题仍然存在。例如,当我通过 Yandex 提供商登录时,它仍然通过我的 Google 帐户登录。
这是我的 authOptions 的样子:
adapter: PrismaAdapter(prisma),
session: {
strategy: "jwt"
},
pages: {
signIn: "/login",
},
secret: process.env.NEXTAUTH_SECRET,
providers: [
GoogleProvider({
clientId: loadCreds().clientId,
clientSecret: loadCreds().clientSecret,
authorization: {
params: {
prompt: "consent",
access_type: "offline",
response_type: "code"
}
}
}),
YandexProvider({
clientId: process.env.YANDEX_CLIENT_ID as string,
clientSecret: process.env.YANDEX_CLIENT_SECRET as string
})
],
callbacks: {
async jwt({ token, user }) {
if (user) {
const candidate = await prisma.user.findFirst({ where: { id: token.id as string } })
if (!candidate) {
token.id = user!.id
return token
} else {
return {
id: candidate.id,
name: candidate.name,
email: candidate.email,
image: candidate.image
}
}
} else {
return token
}
},
async session({ session, token }) {
session.user!.name = token.name
session.user!.email = token.email
session.user!.image = token.image as string
return session
},
redirect() {
return "/"
}
}
我尝试过清除浏览器中的缓存和 cookie、删除 .next 文件夹、检查文档,但仍然无法弄清楚我在哪里犯了错误。
查看数据库中您的用户。在使用数据库适配器的默认设置中,首次登录将创建一个
Account
,其中 provider
字段中包含 oauth 提供程序值的名称。
provider
provider: string;
Provider’s id for this account. Eg.: “google”
下次登录时,它会在数据库中查找匹配的
Account
,其中包括该 provider
字段。
清除缓存/cookies或切换设备/浏览器不会改变行为,因为它不会影响数据库中存储的内容。
不幸的是,据我所知,没有一个简单的解决方法。这取决于一些进一步的细节。但也许我可以通过抛出一些想法来获得一些启示:
您可以更新架构以存储多个提供程序并添加逻辑以添加和检查正确的提供程序
或创建多个帐户并链接它们
或添加一个步骤,以便在下次身份验证之前根据需要更新提供商字段
如果您指的是单击一个显示“provider 1”登录的按钮,但它会将您重定向到“provider 2”的登录屏幕,您可以添加一个条件以转到该按钮指定的提供程序,而不是让 next-身份验证重定向到在
Account
上找到的提供商
您还可以考虑通过修改 Prisma 适配器并根据您的用例使用
linkAccount
fn 来创建“自定义”适配器。
https://authjs.dev/reference/core/adapters#linkaccount
但是,如果您不小心,这会带来漏洞的机会,因此,如果您走这条路,请仔细检查!
再次强调,它们都不是伟大或简单的解决方案,但希望这能为您提供一条摆脱困境的途径(直到下一期😉)!
祝你好运!