如何基于NextAuth实现多登录页并调用指定API路由
解决NextAuth多登录页+动态API路由的方案
核心思路是通过自定义登录标识区分登录场景,在NextAuth配置中动态切换API调用,并通过会话控制跳转路由,具体实现步骤如下:
1. 独立登录页面配置
为owner和user分别创建登录页面,调用signIn时传递自定义标识和目标跳转地址:
商家登录页(pages/owner/login.jsx)
import { signIn } from "next-auth/react" export default function OwnerLogin() { return ( <form onSubmit={(e) => { e.preventDefault() const { email, password } = e.target signIn("credentials", { email: email.value, password: password.value, callbackUrl: "/owner/dashboard", loginType: "owner" // 自定义标识,标记商家登录 }) }}> <input type="email" name="email" placeholder="商家邮箱" required /> <input type="password" name="password" placeholder="密码" required /> <button type="submit">商家登录</button> </form> ) }
用户登录页(pages/user/login.jsx)
import { signIn } from "next-auth/react" export default function UserLogin() { return ( <form onSubmit={(e) => { e.preventDefault() const { email, password } = e.target signIn("credentials", { email: email.value, password: password.value, callbackUrl: "/user/profile", loginType: "user" // 自定义标识,标记普通用户登录 }) }}> <input type="email" name="email" placeholder="用户邮箱" required /> <input type="password" name="password" placeholder="密码" required /> <button type="submit">用户登录</button> </form> ) }
2. NextAuth核心配置动态处理API路由
在pages/api/auth/[...nextauth].js中,通过CredentialsProvider的authorize方法根据loginType动态调用对应API,并通过JWT存储登录标识用于后续跳转:
import NextAuth from "next-auth" import CredentialsProvider from "next-auth/providers/credentials" import jwt from "jsonwebtoken" export default NextAuth({ providers: [ CredentialsProvider({ name: "Credentials", // 声明接收自定义参数loginType credentials: { email: { label: "邮箱", type: "email" }, password: { label: "密码", type: "password" }, loginType: { label: "登录类型", type: "hidden" } }, async authorize(credentials) { const { email, password, loginType } = credentials // 根据登录类型切换API地址 const apiRoute = loginType === "owner" ? "/api/owner" : "/api/user" // 调用对应角色的认证API const res = await fetch(`${process.env.NEXTAUTH_URL}${apiRoute}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email, password }) }) const user = await res.json() // 认证成功则返回用户信息+登录类型 if (res.ok && user) return { ...user, loginType } return null } }) ], session: { strategy: "jwt" }, // 用JWT存储会话信息 jwt: { // 将loginType写入JWT async encode({ secret, token }) { if (token?.loginType) token.loginType = token.loginType return jwt.sign(token, secret) }, async decode({ secret, token }) { return jwt.verify(token, secret) } }, callbacks: { // 控制登录后的跳转逻辑 async redirect({ url, baseUrl }) { const session = await getSession() // 根据会话中的loginType跳转对应页面 if (session?.user?.loginType === "owner") { return `${baseUrl}/owner/dashboard` } else if (session?.user?.loginType === "user") { return `${baseUrl}/user/profile` } // 兜底返回默认地址 return url.startsWith(baseUrl) ? url : baseUrl } } })
3. 实现角色专属认证API
分别创建商家和用户的认证API,处理各自的账号校验逻辑:
商家认证API(pages/api/owner.js)
export default async function handler(req, res) { if (req.method !== "POST") return res.status(405).json({ msg: "仅支持POST请求" }) const { email, password } = req.body // 此处替换为商家账号校验逻辑(比如查询数据库) const validOwner = await checkOwnerCredentials(email, password) if (validOwner) { res.status(200).json({ id: validOwner.id, email: validOwner.email, role: "owner" }) } else { res.status(401).json({ msg: "商家账号或密码错误" }) } }
用户认证API(pages/api/user.js)
export default async function handler(req, res) { if (req.method !== "POST") return res.status(405).json({ msg: "仅支持POST请求" }) const { email, password } = req.body // 此处替换为普通用户账号校验逻辑 const validUser = await checkUserCredentials(email, password) if (validUser) { res.status(200).json({ id: validUser.id, email: validUser.email, role: "user" }) } else { res.status(401).json({ msg: "用户账号或密码错误" }) } }
关键说明
- 自定义
loginType参数是核心,用于在NextAuth流程中区分不同登录场景 - 使用JWT会话策略可以持久化登录类型,确保跳转逻辑准确
- 若需复用登录表单,可以封装通用组件,通过props传递
loginType和callbackUrl
内容的提问来源于stack exchange,提问作者Himanshu Gogoi
相关产品推荐
相关产品推荐

