feat: 1. 完善全局路由的访问权限的验证。 2. 完善接口返回的树形路由结构 3.优化评查点列表的查询,改用表连接的方式,废弃使用数据库的rpc函数,同时进行地区隔离和权限隔离。
4. 删除冗余的评查文件列表。 5.完善上传文档 页面初始化查询数据的时候 查询文件类型(改成动态指定) 6. 添加获取入口模块的查询接口。 7.完善服务端中判断token的有效性,失效则跳转到登录页。 8. 重构layout和sidebar的页面,改成由动态权限路由来渲染对应的菜单栏。 9.重构入口页面,通过动态查询根据不同地区的人返回不同的入口。
This commit is contained in:
+36
-26
@@ -126,33 +126,47 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
||||
try {
|
||||
const { getUserSession } = await import("~/api/login/auth.server");
|
||||
const session = await getUserSession(request);
|
||||
userRole = session.userRole || 'common';
|
||||
userRole = session.userRole;
|
||||
frontendJWT = session.frontendJWT || null;
|
||||
// console.log("🔑 [Root Loader] 用户角色:", userRole);
|
||||
|
||||
// 🔑 检查用户角色和JWT是否为空
|
||||
if (!userRole || userRole === '') {
|
||||
console.error("❌ [Root Loader] 用户角色为空,session数据异常");
|
||||
// 保存当前路径,登录后可以跳转回来
|
||||
const redirectTo = pathname !== '/login' ? pathname : '/';
|
||||
return redirect(`/login?redirect=${encodeURIComponent(redirectTo)}&error=no_role`);
|
||||
}
|
||||
|
||||
if (!frontendJWT) {
|
||||
console.error("❌ [Root Loader] JWT token为空,session数据异常");
|
||||
// 保存当前路径,登录后可以跳转回来
|
||||
const redirectTo = pathname !== '/login' ? pathname : '/';
|
||||
return redirect(`/login?redirect=${encodeURIComponent(redirectTo)}&error=no_token`);
|
||||
}
|
||||
|
||||
// console.log("🔑 [Root Loader] 用户角色:", userRole, "JWT前20字符:", frontendJWT.substring(0, 20));
|
||||
|
||||
// 🔒 RBAC 路由权限检查
|
||||
if (frontendJWT) {
|
||||
const { getUserRoutesByRole } = await import("~/api/auth/user-routes");
|
||||
// 权限校验需要包含隐藏路由,确保用户可以访问隐藏的功能页面
|
||||
const routesResult = await getUserRoutesByRole(userRole, frontendJWT, true);
|
||||
const { getUserRoutesByRole } = await import("~/api/auth/user-routes");
|
||||
// 权限校验需要包含隐藏路由,确保用户可以访问隐藏的功能页面
|
||||
const routesResult = await getUserRoutesByRole(userRole, frontendJWT, true);
|
||||
|
||||
if (routesResult.success && routesResult.data) {
|
||||
// 从菜单数据中提取所有允许的路径
|
||||
allowedPaths = extractAllPaths(routesResult.data);
|
||||
// console.log("🔑 [Root Loader] 用户允许的路由:", allowedPaths);
|
||||
if (routesResult.success && routesResult.data) {
|
||||
// 从菜单数据中提取所有允许的路径
|
||||
allowedPaths = extractAllPaths(routesResult.data);
|
||||
// console.log("🔑 [Root Loader] 用户允许的路由:", allowedPaths);
|
||||
|
||||
// 检查当前路径是否在允许列表中
|
||||
const isAllowedPath = isPathAllowed(pathname, allowedPaths);
|
||||
// 检查当前路径是否在允许列表中
|
||||
const isAllowedPath = isPathAllowed(pathname, allowedPaths);
|
||||
|
||||
if (!isAllowedPath) {
|
||||
console.warn(`⚠️ [Root Loader] 用户尝试访问未授权路由: ${pathname}`);
|
||||
// 返回 403 错误,而不是 redirect(避免循环)
|
||||
throw new Response("无权访问此页面", { status: 403 });
|
||||
}
|
||||
} else {
|
||||
// 获取路由权限失败,只记录警告,不阻止访问(避免影响正常使用)
|
||||
console.warn("⚠️ [Root Loader] 获取用户路由权限失败,跳过权限检查");
|
||||
if (!isAllowedPath) {
|
||||
console.warn(`⚠️ [Root Loader] 用户尝试访问未授权路由: ${pathname}`);
|
||||
// 返回 403 错误,而不是 redirect(避免循环)
|
||||
throw new Response("无权访问此页面", { status: 403 });
|
||||
}
|
||||
} else {
|
||||
// 获取路由权限失败,只记录警告,不阻止访问(避免影响正常使用)
|
||||
console.warn("⚠️ [Root Loader] 获取用户路由权限失败,跳过权限检查");
|
||||
}
|
||||
} catch (error) {
|
||||
// 如果是 Response 对象(403 错误),直接抛出
|
||||
@@ -171,13 +185,9 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
||||
console.warn("⚠️ [Root Loader] 获取用户会话失败:", error);
|
||||
// 保持默认值 'common'
|
||||
}
|
||||
}
|
||||
|
||||
// ⚠️ 重要:现在使用客户端 localStorage 存储 token,服务端不再检查 session
|
||||
// 认证检查改为在客户端进行(通过 ClientAuthGuard 组件)
|
||||
|
||||
if (!frontendJWT) {
|
||||
frontendJWT = getAccessToken();
|
||||
// 注意:认证检查和重定向已在 getUserSession() 中统一处理
|
||||
// 如果执行到这里,说明已通过认证或是公共路径
|
||||
}
|
||||
|
||||
// 检查51707端口访问控制
|
||||
|
||||
Reference in New Issue
Block a user