You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中JWT角色授权问题:如何阻止伪造令牌进入管理员路由

问题描述

我在localStorage中存储JWT,示例令牌:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiVVNFUiIsImlhdCI6MTY2MjU1NzE3Mn0.lRbHWxk8kSnTH8Okdko3cK8Nkce-0sNSeTNjQa1m33o

该令牌的Payload如下:

{
  "role": "USER",
  "iat": 1662557172
}

我的前端有一个受保护路由,通过解码JWT并校验角色控制访问,代码如下:

if (jwt_decode(auth.user).role!=="ADMIN") {
        return <Navigate to="/home" />
    }
    return children

当前问题:用户可手动创建含"ADMIN"角色的令牌,虽无法调用API,但能进入管理员路由,请问如何阻止该情况?

解决方案

核心问题是前端只解码JWT的Payload内容,没有验证令牌的合法性——伪造的令牌没有后端的有效签名,只要前端不做签名校验,就会被当成有效令牌处理。要解决这个问题,必须在前端路由校验时,同步验证JWT的签名有效性,确保令牌是后端合法签发的。

具体实现步骤:

  • 使用支持签名验证的JWT库:放弃仅解码Payload的工具,改用jsonwebtoken或jose这类能验证签名的库。后端签发令牌时用的密钥(对称加密)或公钥(非对称加密),前端需要持有对应密钥用于校验。

    示例代码(以jsonwebtoken为例):

    import jwt from 'jsonwebtoken';
    
    // 注意:如果是对称加密,这里的密钥要和后端完全一致;非对称加密则用后端提供的公钥
    const VALIDATION_KEY = '后端签发令牌用的密钥/公钥';
    
    const ProtectedAdminRoute = ({ children }) => {
      const auth = JSON.parse(localStorage.getItem('auth'));
      if (!auth?.user) {
        return <Navigate to="/home" />;
      }
    
      try {
        // 同时完成签名验证和令牌解码
        const decodedToken = jwt.verify(auth.user, VALIDATION_KEY);
        // 验证角色权限
        if (decodedToken.role !== 'ADMIN') {
          return <Navigate to="/home" />;
        }
      } catch (error) {
        // 签名验证失败(令牌伪造、篡改或过期),直接跳转
        return <Navigate to="/home" />;
      }
    
      return children;
    };
    
  • 自动处理令牌过期:jwt.verify会自动校验令牌中的exp(过期时间)字段,只要后端签发令牌时设置了该字段,前端验证时就能自动拦截过期令牌。

  • 前端校验仅为体验优化,后端权限才是核心:即使前端做了签名验证,后端仍需在每个敏感API接口中重复校验令牌的签名和角色——这是防止非法访问的最后一道防线。前端校验只是避免用户进入无权限页面后才发现无法操作,提升体验而已。

另外,如果担心对称加密密钥暴露在前端代码中,建议改用非对称加密方案:后端用私钥签发令牌,前端用公钥验证签名,公钥可以安全地嵌入前端代码,不会带来安全风险。

内容的提问来源于stack exchange,提问作者Wael Ben Mustapha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 02:17:35