NextJS如何复用动态路由,无需req.query实现管理员编辑用户资料?
解决方法
首先,你的路由文件夹结构pages/edit/[userId]/index.jsx已经符合Next.js动态路由的要求,核心是直接通过路由路径传递userId,同时区分普通用户和管理员的访问逻辑:
1. 调整访问路径
- 普通用户编辑自身资料:访问
/user/edit,我们把这个路径作为入口,自动重定向到/edit/[当前用户ID] - 管理员编辑指定用户:直接访问
/edit/[目标用户ID](比如/edit/123)
2. 实现普通用户的重定向页面
新建pages/user/edit.jsx,作为普通用户的编辑入口,自动跳转到自己的动态路由页面:
import { useEffect } from 'react'; import { useRouter } from 'next/router'; export default function UserEditRedirect() { const router = useRouter(); // 这里替换成你获取当前登录用户ID的逻辑(比如从Auth状态、Session中读取) const currentUserId = '当前登录用户的ID'; useEffect(() => { if (currentUserId) { router.push(`/edit/${currentUserId}`); } }, [currentUserId, router]); return <div>跳转中...</div>; }
3. 在动态路由页面获取userId并处理权限
在pages/edit/[userId]/index.jsx中,直接从动态路由参数获取userId,无需依赖URL query:
客户端获取(适用于客户端渲染场景)
import { useRouter } from 'next/router'; import { useState, useEffect } from 'react'; export default function EditUserPage() { const router = useRouter(); const { userId } = router.query; // 这里的userId是动态路由参数,不是URL query参数 const [userData, setUserData] = useState(null); // 替换成你获取当前登录用户信息的逻辑 const currentUser = { id: '当前用户ID', isAdmin: false }; useEffect(() => { if (!userId) return; // 权限校验:普通用户只能编辑自己的资料 if (!currentUser.isAdmin && userId !== currentUser.id) { router.push(`/edit/${currentUser.id}`); return; } // 根据userId获取目标用户的资料 fetch(`/api/users/${userId}`) .then(res => res.json()) .then(data => setUserData(data)); }, [userId, currentUser, router]); if (!userData) return <div>加载中...</div>; return ( <div> <h2>编辑用户:{userData.name}</h2> {/* 你的编辑表单 */} <input type="text" defaultValue={userData.name} /> {/* 其他表单字段 */} </div> ); }
服务端获取(适用于服务端渲染场景,更安全)
import { useRouter } from 'next/router'; // 服务端获取数据并做权限校验 export async function getServerSideProps(context) { // Next.js 13+ Pages Router用context.params获取路由参数,旧版本用context.query.userId const { userId } = context.params; // 从请求中获取当前登录用户信息(比如从Session、Cookie中读取) const currentUser = await getCurrentUserFromSession(context.req); // 未登录用户跳转登录页 if (!currentUser) { return { redirect: { destination: '/login', permanent: false } }; } // 普通用户只能编辑自己的资料 if (!currentUser.isAdmin && userId !== currentUser.id) { return { redirect: { destination: `/edit/${currentUser.id}`, permanent: false } }; } // 获取目标用户的资料 const userData = await fetchUserById(userId); return { props: { userData, currentUser } }; } export default function EditUserPage({ userData, currentUser }) { return ( <div> <h2>编辑用户:{userData.name}</h2> {/* 你的编辑表单 */} <input type="text" defaultValue={userData.name} /> {/* 其他表单字段 */} </div> ); } // 以下是示例工具函数,替换成你项目中的实际实现 async function getCurrentUserFromSession(req) { // 从req中获取当前登录用户逻辑 return { id: '当前用户ID', isAdmin: false }; } async function fetchUserById(userId) { // 根据ID获取用户数据逻辑 return { id: userId, name: '目标用户名称' }; }
关键注意点
- 权限校验必须做:不管是客户端还是服务端,都要校验当前用户是否有权限编辑目标用户,防止普通用户手动输入其他用户ID越权操作
- 动态路由参数的获取:客户端用
router.query.userId,服务端在Next.js 13+ Pages Router中用context.params.userId,旧版本用context.query.userId(这里的query是路由参数,不是URL上的?xxx参数)
内容的提问来源于stack exchange,提问作者Kal
相关产品推荐
相关产品推荐

