我正在实现 Next-Auth 的“CredentialsProvider”,到目前为止,我已经看到了一些示例,其中我只能在其中添加文本字段,例如“用户名”和“密码”。
是否可以添加“菜单列表”之类的东西?这基本上会给我们一些选择?我这样做基本上是为了向用户提供一个以用户或管理员身份登录的选项,方法是从下拉菜单中选择其中任何一个(类似于下图中的设计)
我尝试过“收音机”选项,但这不是我想要的。
NextAuth.js 中的凭证提供程序主要用于简单的用户名/密码身份验证。正如您所描述的,它不提供对更复杂的表单或下拉菜单的内置支持。不过,您可以通过自定义登录页面来实现您想要的功能。
具体操作方法如下:
创建自定义登录页面: 您可以在 Next.js 应用程序中创建自定义登录页面,而不是使用 NextAuth.js 提供的默认登录页面。此自定义页面可以包含您需要的任何表单元素,包括下拉菜单。
实现下拉菜单:在自定义登录页面中,您可以添加 HTML 元素来创建下拉菜单。您可以使用“用户”和“管理员”等选项填充此下拉列表。
<select name="role">
<option value="user">User</option>
<option value="admin">Admin</option>
</select>
处理表单提交:当用户提交表单时,您可以从表单提交处理程序的下拉菜单中访问所选值。根据所选角色(“用户”或“管理员”),您可以使用适当的逻辑对用户进行身份验证。 以下是带有下拉菜单的自定义登录页面的简化示例:
import { useState } from 'react';
import { signIn } from 'next-auth/react';
export default function CustomSignIn() {
const [role, setRole] = useState('user'); // Default role is "User"
const handleSignIn = async (e) => {
e.preventDefault();
// Use the selected role when signing in
const result = await signIn('credentials', {
role,
// Other credentials like username and password
});
// Handle the sign-in result as needed
};
return (
<div>
<h2>Custom Sign In</h2>
<form onSubmit={handleSignIn}>
<label>
Role:
<select name="role" value={role} onChange={(e) => setRole(e.target.value)}>
<option value="user">User</option>
<option value="admin">Admin</option>
</select>
</label>
{/* Other input fields like username and password */}
<button type="submit">Sign In</button>
</form>
</div>
);
}
通过这种方法,您可以完全控制登录表单的外观和行为,包括添加用户角色的下拉菜单。
请记住,凭据提供程序的主要目的是根据提供的凭据(例如用户名和密码)处理身份验证。它不规定登录页面的结构或外观,让您可以根据需要灵活地实现自定义表单。
注:
默认情况下,NextAuth.js 会自动创建简单的、无品牌的身份验证页面,用于处理登录、注销、电子邮件验证和显示错误消息。
要添加自定义登录页面,您可以使用页面选项: 确保在 NextAuth 配置中使用 key SignIn 添加页面属性,它告诉 NextAuth 要使用什么自定义页面:
pages: {
signIn: "/login",
// signOut: "/login",
// error: "/auth/error", // Error code passed in query string as ?error=
// verifyRequest: "/auth/verify-request", // (used for check email message)
// newUser: "/auth/new-user", // New users will be directed here on first sign in (leave the property out if not of interest)
},