next-auth使用Credentials凭证登录报错

auth.ts:
import NextAuth from 'next-auth';
import GitHub from 'next-auth/providers/github';
import Credentials from 'next-auth/providers/credentials';
export const { handlers, signIn, signOut, auth } = NextAuth({
providers: [
GitHub,
Credentials({
credentials: {
email: {},
password: {},
},
authorize: async (credentials) => {
console.log('鉴权---authorize', credentials);
return {
id: '1',
name: 'crayming',
email: 'crayming@example.com',
image: null,
};
},
}),
],
});
login.tsx:
import { signIn } from '@/auth';
export default function SignIn() {
return (
<form
action={async (formData) => {
'use server';
try {
const res = await signIn('credentials', formData);
console.log('hello world');
} catch (e) {
console.log('登录失败' + JSON.stringify(e));
}
}}
>
<label>
Email
<input name="email" />
</label>
<label>
Password
<input name="password" type="password" />
</label>
<button>Sign In</button>
</form>
);
}
点击登录,进入了 catch 块, 控制台报错:登录失败{"digest":"NEXT_REDIRECT;push;http://localhost:8080/login3;307;"}
这个错误信息表明 NextAuth 在尝试进行重定向操作,但在服务器组件或服务器操作中被捕获为错误。这是因为:
- 重定向被当作错误处理:在 Next.js 的服务器操作(Server Actions)中,重定向操作会被抛出为一个特殊类型的错误,这个错误包含了重定向的信息。
- 错误的本质:这不是真正的错误,而是 Next.js 内部用来处理重定向的机制。当你在 try/catch 块中捕获它时,它会被当作错误处理。
- 307 状态码:这是一个临时重定向状态码,表示请求应该使用另一个 URI 重新发出。
解决方案
这个问题的解决方法是告诉 NextAuth 不要在登录时自动重定向。通过以下方式修改代码:
import { signIn } from '@/auth';
export default function SignIn() {
return (
<form
action={async (formData) => {
'use server';
try {
// 添加 redirect: false 参数以防止自动重定向
const res = await signIn('credentials', {
redirect: false,
email: formData.get('email'),
password: formData.get('password')
});
console.log('登录结果', res);
} catch (e) {
console.log('登录失败' + JSON.stringify(e));
}
}}
>
<label>
Email
<input name="email" />
</label>
<label>
Password
<input name="password" type="password" />
</label>
<button>Sign In</button>
</form>
);
}
解释
- 添加
redirect: false
参数:
这告诉 NextAuth 不要在登录成功或失败后自动重定向,而是返回一个结果对象。 - 从 FormData 中提取字段:
使用formData.get('email')
和formData.get('password')
来明确提取表单中的字段,而不是直接传递整个 FormData 对象。 - 记录登录结果:
使用console.log('登录结果', res)
来记录登录的结果,这样可以看到登录是成功还是失败,以及返回的具体信息。
为什么会发生这个问题
在 Next.js 的服务器操作中,NextAuth 的 signIn
函数默认会在以下情况下尝试重定向:
- 登录成功时 - 重定向到成功页面或指定的回调 URL
- 登录失败时 - 重定向到错误页面或登录页面
但是,在服务器组件或服务器操作中,这种重定向会被作为一个特殊类型的错误抛出,因为服务器组件不能直接控制浏览器的导航。
通过设置 redirect: false
,我们告诉 NextAuth 不要尝试重定向,而是简单地返回登录结果,这样我们就可以在代码中自己处理成功或失败的情况,而不会触发那个被捕获为错误的重定向操作。
现在,尝试登录时,应该不会再看到那个重定向错误,而是可以看到实际的登录结果,这样就可以根据结果来决定下一步操作。
版权声明:
作者:东明兄
链接:https://blog.crazyming.com/note/3249/
来源:CrazyMing
文章版权归作者所有,未经允许请勿转载。


共有 0 条评论