Next.js 13中用NextAuth保护个人资料API路由遇路由问题求助
问题分析与修复方案
你当前的核心问题是混淆了Next.js Pages Router和App Router的API路由写法,同时误用了NextAuth的会话获取方式,导致权限校验逻辑无法正常工作。以下是具体修复步骤:
1. 替换NextAuth会话获取方法
在App Router环境下,不能使用next-auth/react中的getSession(这是给客户端组件用的),必须改用服务端的getServerSession,并传入你的NextAuth配置文件。
2. 调整API路由结构(符合App Router规范)
App Router的API路由处理函数参数不是传统的(req, res),而是接收context对象,路由参数、请求对象都在这个context里;响应也需要直接用NextResponse返回,不需要依赖res对象。
3. 修正后的代码示例
权限校验工具函数(抽离复用)
// @utils/requireAuth.js import { getServerSession } from "next-auth/next"; import { authOptions } from "@/app/api/auth/[...nextauth]/route"; // 引入你的NextAuth配置 import { NextResponse } from "next/server"; export async function requireAuth(context) { const session = await getServerSession(authOptions); const { id } = context.params; // 从context获取路由参数 // 未登录则跳转登录页 if (!session) { return NextResponse.redirect(new URL("/login", context.request.url)); } // 员工ID不匹配返回401 if (session.user.EmployeeID !== id) { return NextResponse.json({ error: "无权访问此资源" }, { status: 401 }); } // 校验通过,返回null继续执行后续逻辑 return null; }
修正后的API路由文件(路径:app/api/user/[id]/route.js)
import User from "@models/user"; import { ConnectToDb } from "@utils/db"; import { NextResponse } from "next/server"; import { requireAuth } from "@utils/requireAuth"; // 处理GET请求 export async function GET(request, context) { // 先执行权限校验 const authCheck = await requireAuth(context); if (authCheck) return authCheck; const { id } = context.params; try { await ConnectToDb(); const user = await User.findOne({ EmployeeID: id }); if (!user) { return NextResponse.json({ error: "用户不存在" }, { status: 404 }); } return NextResponse.json({ user }, { status: 200 }); } catch (error) { return NextResponse.json({ error: error.message }, { status: 500 }); } } // 如需处理其他HTTP方法,单独声明即可 // export async function POST(request, context) { // const authCheck = await requireAuth(context); // if (authCheck) return authCheck; // // 你的POST逻辑 // }
额外注意事项
- 确认你的NextAuth会话中确实包含
user.EmployeeID字段,可在登录回调(callbacks.jwt和callbacks.session)中检查该字段是否被正确传递。 - 路由文件必须放在
app/api/user/[id]/route.js路径下,才能正确捕获URL中的123456作为id参数。
内容的提问来源于stack exchange,提问作者Kabir Raj Singh
相关产品推荐
相关产品推荐

