如何在Next-Auth的CredentialsProvider中添加登录角色选择下拉菜单?
在Next-Auth的CredentialsProvider中添加角色选择下拉菜单
当然可以,Next-Auth完全支持自定义登录表单,你可以轻松添加下拉菜单来让用户选择登录角色,无需局限于默认的文本字段。下面是具体实现步骤:
1. 自定义登录页面
Next-Auth的默认登录页无法直接修改字段,所以需要创建一个自定义登录页。根据你的路由模式(Pages Router/App Router)创建对应的组件:
Pages Router 示例(pages/auth/signin.js)
import { signIn } from "next-auth/react"; export default function SignIn() { return ( <form onSubmit={(e) => { e.preventDefault(); const formData = new FormData(e.target); signIn("credentials", { username: formData.get("username"), password: formData.get("password"), role: formData.get("role"), callbackUrl: "/", // 登录后跳转的页面 }); }} > <div> <label>用户名</label> <input type="text" name="username" required /> </div> <div> <label>密码</label> <input type="password" name="password" required /> </div> <div> <label>登录角色</label> <select name="role" required> <option value="User">普通用户</option> <option value="Admin">管理员</option> </select> </div> <button type="submit">登录</button> </form> ); }
App Router 示例(app/auth/signin/page.js)
"use client"; import { signIn } from "next-auth/react"; export default function SignIn() { return ( <form onSubmit={(e) => { e.preventDefault(); const formData = new FormData(e.target); signIn("credentials", { username: formData.get("username"), password: formData.get("password"), role: formData.get("role"), callbackUrl: "/", }); }} > <div> <label>用户名</label> <input type="text" name="username" required /> </div> <div> <label>密码</label> <input type="password" name="password" required /> </div> <div> <label>登录角色</label> <select name="role" required> <option value="User">普通用户</option> <option value="Admin">管理员</option> </select> </div> <button type="submit">登录</button> </form> ); }
2. 配置CredentialsProvider
在你的Next-Auth配置文件(pages/api/auth/[...nextauth].js 或 app/api/auth/[...nextauth]/route.js)中,更新CredentialsProvider的配置,新增role字段,并在authorize函数中处理角色信息:
Pages Router 配置示例
import NextAuth from "next-auth"; import CredentialsProvider from "next-auth/providers/credentials"; export const authOptions = { providers: [ CredentialsProvider({ name: "Credentials", // 定义表单字段,新增role credentials: { username: { label: "用户名", type: "text" }, password: { label: "密码", type: "password" }, role: { label: "角色", type: "text" }, }, async authorize(credentials, req) { // 这里替换为你的实际用户验证逻辑 // 比如从数据库查询用户,验证用户名、密码和角色匹配 const validUser = credentials.username === "test" && credentials.password === "test"; if (validUser) { // 返回包含角色的用户信息 return { id: "1", name: credentials.username, role: credentials.role, }; } // 验证失败返回null return null; }, }), ], // 通过callbacks将角色存入JWT和Session callbacks: { jwt: ({ token, user }) => { if (user) token.role = user.role; return token; }, session: ({ session, token }) => { if (session.user) session.user.role = token.role; return session; }, }, }; export default NextAuth(authOptions);
App Router 配置示例
import NextAuth from "next-auth"; import CredentialsProvider from "next-auth/providers/credentials"; const handler = NextAuth({ providers: [ CredentialsProvider({ name: "Credentials", credentials: { username: { label: "用户名", type: "text" }, password: { label: "密码", type: "password" }, role: { label: "角色", type: "text" }, }, async authorize(credentials, req) { const validUser = credentials.username === "test" && credentials.password === "test"; if (validUser) { return { id: "1", name: credentials.username, role: credentials.role, }; } return null; }, }), ], callbacks: { jwt: ({ token, user }) => { if (user) token.role = user.role; return token; }, session: ({ session, token }) => { if (session.user) session.user.role = token.role; return session; }, }, }); export { handler as GET, handler as POST };
3. 使用角色信息
登录成功后,你可以通过useSession钩子在前端获取用户的角色信息:
"use client"; import { useSession } from "next-auth/react"; export default function Profile() { const { data: session } = useSession(); return ( <div> <p>当前用户: {session?.user?.name}</p> <p>当前角色: {session?.user?.role}</p> </div> ); }
内容的提问来源于stack exchange,提问作者Syed Khureshi
相关产品推荐
相关产品推荐

