我正在使用next-auth构建一个nextjs应用程序。现在我已经登录谷歌,凭据和github。如果我登录谷歌,其中包含电子邮件“example@gmail.com“,然后我注销,如果我尝试登录github,但与帐户有相同的电子邮件“example@gmail.com”,我得到错误:O验证帐户未链接
在next-auth提供给我们的数据库模型中,用户与帐户的关系是一个数组,所以我认为这将是可能的,但喜欢与2个帐户的sabe用户。我忘了什么,或者这是默认行为?
我的[... nextAuth].ts代码
export const handler = async (req: NextApiRequest, res: NextApiResponse) => {
const data = requestWrapper(req, res);
return await NextAuth(...data);
};
export default handler;
export function requestWrapper(
req: NextApiRequest,
res: NextApiResponse
): [req: NextApiRequest, res: NextApiResponse, opts: NextAuthOptions] {
const generateSessionToken = () => randomUUID();
const fromDate = (time: number, date = Date.now()) =>
new Date(date + time * 1000);
const adapter = PrismaAdapter(prisma);
const opts: NextAuthOptions = {
// Include user.id on session
adapter: adapter,
pages: {
signIn: "/login",
},
callbacks: {
session({ session, user }) {
console.log("AAAA");
if (session.user) {
session.user = user;
}
return session;
},
async signIn({ user, account, profile, email, credentials }) {
// Check if this sign in callback is being called in the credentials authentication flow. If so, use the next-auth adapter to create a session entry in the database (SignIn is called after authorize so we can safely assume the user is valid and already authenticated).
if (
req.query.nextauth?.includes("callback") &&
req.query.nextauth?.includes("credentials") &&
req.method === "POST"
) {
if (user) {
const sessionToken = generateSessionToken();
const sessionMaxAge = 60 * 60 * 24 * 30; //30Daysconst sessionMaxAge = 60 * 60 * 24 * 30; //30Days
const sessionExpiry = fromDate(sessionMaxAge);
await adapter.createSession({
sessionToken: sessionToken,
userId: user.id,
expires: sessionExpiry,
});
const cookies = new Cookies(req, res);
cookies.set("next-auth.session-token", sessionToken, {
expires: sessionExpiry,
});
}
}
return true;
},
},
jwt: {
encode: async ({ token, secret, maxAge }) => {
if (
req.query.nextauth?.includes("callback") &&
req.query.nextauth.includes("credentials") &&
req.method === "POST"
) {
const cookies = new Cookies(req, res);
const cookie = cookies.get("next-auth.session-token");
if (cookie) return cookie;
else return "";
}
// Revert to default behaviour when not in the credentials provider callback flow
return encode({ token, secret, maxAge });
},
decode: async ({ token, secret }) => {
if (
req.query.nextauth?.includes("callback") &&
req.query.nextauth.includes("credentials") &&
req.method === "POST"
) {
return null;
}
// Revert to default behaviour when not in the credentials provider callback flow
return decode({ token, secret });
},
},
// Configure one or more authentication providers
secret: process.env.NEXTAUTH_SECRET,
// debug: true,
providers: [
GithubProvider({
clientId: process.env.GITHUB_ID as string,
clientSecret: process.env.GITHUB_SECRET as string,
profile(profile, token) {
return {
id: profile.id.toString(),
name: profile.name || profile.login,
image: profile.avatar_url,
email: profile.email,
role: Role.USER,
};
},
}),
GoogleProvider({
clientId: process.env.GOOGLE_ID as string,
clientSecret: process.env.GOOGLE_SECRET as string,
authorization: {
params: {
prompt: "consent",
access_type: "offline",
response_type: "code",
},
},
}),
CredentialProvider({
name: "CredentialProvider",
credentials: {
email: { label: "Email", type: "text", placeholder: "" },
password: { label: "Password", type: "password" },
},
async authorize(credentials: any, _req): Promise<any | null> {
const userInputs = {
email: credentials.email,
password: credentials.password,
};
const { user } = await loginCredentials(userInputs);
if (user) {
return user;
} else {
return null;
}
},
}),
],
};
return [req, res, opts];
}
1条答案
按热度按时间nbysray51#
对我来说,解决这个问题的方法是添加
allowDangerousEmailAccountLinking: true
,它看起来像这样:这样做应该可以解决大多数关于帐户链接的错误,但我肯定很乐意听到有人提出了更好的解决方案。
更多关于这一点:https://next-auth.js.org/configuration/providers/oauth#allowdangerousemailaccountlinking-option