react 路由鉴权方案

文章介绍了三种在React应用中处理登录状态和路由鉴权的方法:一是通过创建Context并广播用户登录状态;二是利用localStorage保存登录状态并组合组件;三是路由前拦截器进行权限检查。这些策略可以单独使用,也可结合使用,以确保用户访问权限的安全控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实现思路一:

1、广播用户登录状态。
2、在路由中消费状态,选择跳转,实现路由鉴权。

请求响应接口处,主要是用于提醒用户登录状态失效,路由鉴权用于跳转登录。

//基础部分
import React, { useContext, useState } from "react";
/**
 * 创建context
 */
const ContextValue = React.createContext();

/**
 * 输出组件
 */
const Auth = () => {
  const [auth_state, setAuthState] = useState(false);
  const logIn = () => {
    // 模拟登录操作 
    setTimeout(() => {
      setAuthState(true);
    }, 200);
  };
  const logOut = () => {
    // 模拟登出操作
    setTimeout(() => {
      setAuthState(true);
    }, 200);
  };
  return {
    auth_state,
    logIn,
    logOut,
  };
};
/**
 *  设置 发布者,一般包裹根组件
 */
export const AuthProvider = ({ children }) => {
  const auth = Auth();
  return <ContextValue.Provider value={auth}>{children}</ContextValue.Provider>;
};
/**
 * 消费者 获取登陆状态 | 设置登录 | 设置登出
 */
export const CosumerAuth = () => useContext(ContextValue);
/**
 * 包裹需要的组件,或者相关路由
 */
export const RequireAuth = props => {
  const { auth_state } = CosumerAuth();
  return auth_state === true ? "已登陆" : "跳转登陆组件去登录";
};
实现思路二:

用浏览器存储 如localStorage保存登录状态,组合成组件,包裹路由

/**
*  RequireAuth 组件相当于一个拦截器,是否返回被拦截的组件要听他的
*/
export const RequireAuth = ({ children }) => {
  const authed = localStorage.getItem('login');
  return authed === 'true' ? ( 
    children
  ) : (
    <Navigate to="/user" replace />
  );
}
思路三:

在渲染路由之前做一个拦截器,判断

1、访问登录页,有token,去主页。

2、访问其他页,无token,去登录页。

3、正常渲染。

const ToPage1 = () => {
  const navigateTo = useNavigate();
  useEffect(() => {
    navigateTo("/page1");
    message.warning("您已经登陆过了!");
  }, []);
  return <></>;
};
const ToLogin = () => {
  const navigateTo = useNavigate();
  useEffect(() => {
    navigateTo("/login");
    message.warning("请登陆后再访问!");
  }, []);
  return <></>;
};
/**
 * 路由拦截
 */
const BeforeRouterEnter = () => {
  const outlet = useRoutes(routes);
  let token = localStorage.getItem("lege-token");
  const location = useLocation();
  // 访问登陆页并且有token
  if (location.pathname === "/login" && token) {
    return <ToPage1 />;
  }
  // 访问其他页并且没有token, 去登陆
  if (location.pathname !== "/login" && !token) {
    return <ToLogin />;
  }
  return outlet;
};
const App = () => {
  return (
    <div className="App">
      <BeforeRouterEnter />
    </div>
  );
};

export default App;

以上几种方式,也可以根据实际情况结合使用!结合redux,后端,用于各类状态的判定

### UmiJS 4 中实现动态路由 在 UmiJS 4 中,可以通过配置 `routers.ts` 文件来定义应用的路由,并利用中间件或高阶组件(HOC) 来实现限控制。对于动态路由而言,可以结合约定式路由和自定义逻辑完成复杂的限管理。 #### 使用 Wrappers 进行 为了对特定路径下的所有子页面实施统一的身份验证机制,在路由配置中使用 `wrappers` 属性是一个常见做法: ```typescript // config/routers.ts export const routes = [ { path: '/', wrappers: ['./Authorized'], // 应用于该节点及其后代的所有请求都会经过 Authorized 组件处理 component: '../layouts', routes: [ { path: '/', redirect: '/home' }, { path: '/home', component: './Home' }, { component: './404' } ] } ]; ``` 此处 `./Authorized` 是一个 HOC 或者 React Component,负责拦截未授访问并重定向到登录页或其他提示界面[^3]。 #### 处理可选参数的动态路由 当涉及到带有 `$` 符号标记的可选项时(如 `/users/$id$`),这些特殊模式允许 URL 参数的存在与否不影响匹配成功与否。因此,在设计策略时需考虑这种情况带来的灵活性以及潜在的安全隐患[^1]。 例如,针对用户详情页面 (`/users/:id`) 的访问可能需要额外检查当前用户的 ID 是否与其所拥有的角色相匹配;而对于不存在具体 ID 的情况则应给予适当响应而非抛出错误。 #### 结合业务需求定制化解决方案 实际项目开发过程中往往还需要根据具体的业务场景调整上述方案。比如某些情况下仅部分功能模块受保护而其他公开区域无需任何限制;又或者是多租户架构下不同客户之间资源隔离的需求等等。此时建议开发者深入理解官方文档所提供的工具链特性,并灵活运用以满足个性化要求[^2]。 ```javascript import React from 'react'; import { history, connect } from 'umi'; const Authorized = ({ children }) => { if (!localStorage.getItem('token')) { history.push('/login'); return null; } return <>{children}</>; }; export default connect()(Authorized); ``` 此代码片段展示了简单的身份验证逻辑:如果本地存储中的 token 为空,则跳转至登录页面;反之继续渲染其包裹的内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值