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

React+SpringBoot架构下如何通过后端JWT工具类完成前端JWT有效性校验

解决方案

一、后端修改(核心解决UserDetails获取问题)

你不需要额外把用户信息存入Cookie,直接注入已有的MyUserDetailsService即可拿到UserDetails参数,修改后的校验接口代码如下:

@Autowired
private MyUserDetailsService myUserDetailsService;

// returns the username
@GetMapping("/authenticate")
public ResponseEntity<?> validateHeaderToken() throws Exception {
    try {
        System.out.println("Attempting to validate token");
        String token = request.getHeader("Authorization");
        token = token.split("Bearer ")[1];
        // 1. 从token中提取用户名
        String username = jwtTokenUtil.extractUsername(token);
        // 2. 调用MyUserDetailsService查询数据库获取对应用户的UserDetails
        UserDetails userDetails = myUserDetailsService.loadUserByUsername(username);
        // 3. 调用全量校验方法完成完整校验
        if (jwtTokenUtil.validateToken(token, userDetails)) {
            return ResponseEntity.ok(username);
        } else {
            throw new Exception("Expired or Invalid Token");
        }
    } catch (Exception e) {
        // 所有异常(token非法、用户不存在、token过期等)统一返回401未授权
        return ResponseEntity.status(401).build();
    }
}

上述代码逻辑可以覆盖所有校验场景:如果token是伪造的、对应用户已被删除、token过期都会校验失败返回401。

二、前端现有逻辑bug修复

你当前前端代码存在语法错误和逻辑缺陷,会导致校验失效,同步修改如下:

1. 修复AuthService的validateToken方法错误

原写法.then("did it")属于语法错误,不会返回接口真实响应,修改为:

validateToken() {
  console.log(" about to try validating");
  return AxiosInstance.get("authenticate")
    .then(res => res.data)
    .catch((err) => {
      console.log(err);
      return null;
    });
}

2. 修复Axios实例Authorization头写死问题

原创建实例时直接读取localStorage的token,后续token更新后实例的请求头不会同步更新,改为用请求拦截器动态添加:

const AxiosInstance = axios.create({
  baseURL: API_BASE_URL,
});

// 请求拦截器:每次发请求前动态拼接Authorization头
AxiosInstance.interceptors.request.use(config => {
  const token = localStorage.getItem("token");
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
}, error => {
  return Promise.reject(error);
});

3. 优化React组件校验逻辑

componentDidMount() {
    this._isMounted = true;
    const token = localStorage.getItem("token");
    // 无token直接跳转登录
    if (!token) {
      this.props.history.push("/login");
      return;
    }
    AuthService.validateToken()
      .then((res) => {
        // 校验失败跳转登录
        if (!res) {
          this.props.history.push("/login");
          return;
        }
        // 校验通过再请求业务数据
        return TicketService.getTickets();
      })
      .then((res) => {
        if (this._isMounted && res) {
          this.setState({ tickets: res.data });
        }
      });
}

componentWillUnmount() {
  this._isMounted = false;
}

内容的提问来源于stack exchange,提问作者mcool

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 18:57:04