You've already forked DataMate
feat(auth): 完善API网关JWT认证和权限控制功能
- 实现网关侧JWT工具类和权限规则匹配器 - 集成JWT认证流程,支持Bearer Token验证 - 添加基于路径和HTTP方法的权限控制机制 - 配置白名单路由规则,优化认证性能 - 更新前端受保护路由组件,实现权限验证 - 添加403禁止访问页面和权限检查逻辑 - 重构登录页面,集成实际认证API调用 - 实现用户信息获取和权限加载功能 - 优化全局异常处理器中的认证错误状态码 - 集成FastJSON2和JJWT依赖库支持
This commit is contained in:
@@ -1,20 +1,53 @@
|
||||
import React from 'react';
|
||||
import { Navigate, useLocation, Outlet } from 'react-router';
|
||||
import { useAppSelector } from '@/store/hooks';
|
||||
import { useAppDispatch, useAppSelector } from '@/store/hooks';
|
||||
import { fetchCurrentUser, markInitialized } from '@/store/slices/authSlice';
|
||||
import {
|
||||
hasPermission,
|
||||
resolveDefaultAuthorizedPath,
|
||||
resolveRequiredPermissionByPath,
|
||||
} from '@/auth/permissions';
|
||||
|
||||
interface ProtectedRouteProps {
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
const ProtectedRoute: React.FC<ProtectedRouteProps> = ({ children }) => {
|
||||
const { isAuthenticated } = useAppSelector((state) => state.auth);
|
||||
const dispatch = useAppDispatch();
|
||||
const { isAuthenticated, token, initialized, loading, permissions } = useAppSelector(
|
||||
(state) => state.auth
|
||||
);
|
||||
const location = useLocation();
|
||||
const requiredPermission = resolveRequiredPermissionByPath(location.pathname);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (initialized || loading) {
|
||||
return;
|
||||
}
|
||||
if (!token) {
|
||||
dispatch(markInitialized());
|
||||
return;
|
||||
}
|
||||
void dispatch(fetchCurrentUser());
|
||||
}, [dispatch, initialized, loading, token]);
|
||||
|
||||
if (!initialized || loading) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!isAuthenticated) {
|
||||
// Redirect to the login page, but save the current location they were trying to go to
|
||||
return <Navigate to="/login" state={{ from: location }} replace />;
|
||||
}
|
||||
|
||||
if (!hasPermission(permissions, requiredPermission)) {
|
||||
const fallbackPath = resolveDefaultAuthorizedPath(permissions);
|
||||
if (location.pathname === fallbackPath) {
|
||||
return <Navigate to="/403" replace />;
|
||||
}
|
||||
return <Navigate to={fallbackPath} replace />;
|
||||
}
|
||||
|
||||
return children ? <>{children}</> : <Outlet />;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user