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

前端获取并存储JWT令牌以解决403错误的问题求助

前端获取并存储JWT令牌以解决403错误的问题求助

兄弟,看你描述的情况,第一次处理JWT确实容易卡在前后端衔接的地方,我帮你一步步拆解问题,解决这个403的问题:

首先,你现在的核心问题是后端注册成功后,没有把JWT正确传递给前端,导致后续请求没有携带认证信息,触发403。而且你之前用的是后端重定向,这种方式前端拿不到响应里的JWT,得调整一下逻辑:

一、先调整后端RegisterController的返回逻辑

原来的重定向操作没法让前端拿到JWT,你需要改成返回包含JWT的响应,或者把JWT放到安全的Cookie里,分两种情况:

情况1:前后端分离/用AJAX提交注册(推荐)

把注册接口改成返回JSON格式的响应,包含JWT和跳转地址:

@PostMapping
public ResponseEntity<Map<String, String>> register(@RequestBody UserRegistrationDto registrationDto) {
    // 你的注册逻辑:调用userService完成注册
    User registeredUser = userService.register(registrationDto);
    // 生成JWT令牌
    String jwtToken = jwtTokenService.generateToken(registeredUser);
    
    // 返回token和跳转地址
    return ResponseEntity.ok(Map.of(
        "token", jwtToken,
        "redirectUrl", "/personal_office"
    ));
}

情况2:服务端渲染页面(用Cookie传递,更安全)

如果是传统服务端渲染(比如Thymeleaf、JSP),可以把JWT放到HttpOnly Cookie里,浏览器会自动携带到后续请求:

@PostMapping
public String register(UserRegistrationDto registrationDto, HttpServletResponse response) {
    User registeredUser = userService.register(registrationDto);
    String jwtToken = jwtTokenService.generateToken(registeredUser);
    
    // 创建HttpOnly Cookie,防止XSS攻击
    Cookie jwtCookie = new Cookie("auth_token", jwtToken);
    jwtCookie.setHttpOnly(true); // 前端JS无法读取,更安全
    jwtCookie.setPath("/"); // 全站请求都携带
    jwtCookie.setMaxAge(24 * 60 * 60); // 有效期1天
    // 生产环境记得开启Secure,只在HTTPS下传输
    // jwtCookie.setSecure(true);
    
    response.addCookie(jwtCookie);
    return "redirect:/personal_office";
}

二、前端处理JWT的存储和携带

针对情况1(AJAX提交):

  1. 阻止默认表单提交:用JS监听注册表单的提交事件,用AJAX发送请求,这样能拿到后端返回的JWT:
// 假设你的注册表单id是register-form
document.getElementById('register-form').addEventListener('submit', async (e) => {
    e.preventDefault(); // 阻止页面刷新
    
    // 收集表单数据
    const formData = new FormData(e.target);
    const userInfo = Object.fromEntries(formData);
    
    try {
        const response = await fetch('/register', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(userInfo),
        });
        
        if (response.ok) {
            const { token, redirectUrl } = await response.json();
            // 把JWT存到localStorage
            localStorage.setItem('auth_token', token);
            // 前端自己跳转到个人中心
            window.location.href = redirectUrl;
        } else {
            // 处理注册失败的提示
            const errorMsg = await response.text();
            alert(`注册失败:${errorMsg}`);
        }
    } catch (err) {
        console.error('注册请求出错:', err);
        alert('网络异常,请重试');
    }
});
  1. 后续请求携带JWT:访问需要认证的页面/接口时,在请求头里带上Authorization: Bearer <token>:
// 封装一个带认证的请求函数
async function sendAuthenticatedRequest(url, options = {}) {
    const token = localStorage.getItem('auth_token');
    if (!token) {
        // 没有token,跳回注册页
        window.location.href = '/host_page';
        return;
    }
    
    // 合并请求头,加上Authorization
    const authOptions = {
        ...options,
        headers: {
            ...options.headers,
            'Authorization': `Bearer ${token}`,
        },
    };
    
    const response = await fetch(url, authOptions);
    
    if (response.status === 403 || response.status === 401) {
        // Token失效或无效,清除存储并跳转
        localStorage.removeItem('auth_token');
        window.location.href = '/host_page';
        alert('登录状态已失效,请重新注册');
    }
    
    return response;
}

// 比如访问个人中心的数据
async function loadPersonalOfficeData() {
    const response = await sendAuthenticatedRequest('/personal_office/data');
    if (response.ok) {
        const data = await response.json();
        // 渲染页面数据
        console.log(data);
    }
}

// 页面加载时调用
window.addEventListener('load', loadPersonalOfficeData);

针对情况2(Cookie传递):

这种情况前端几乎不用做额外操作,浏览器会自动把HttpOnly Cookie带到所有同域请求里,你只需要确保后端的安全配置能正确从Cookie中提取JWT进行验证即可。

三、关键注意事项

  • 安全问题:用localStorage存JWT有XSS风险,如果网站存在XSS漏洞,攻击者能窃取token;用HttpOnly Cookie更安全,但前端无法直接操作token(比如刷新token需要后端单独处理)。
  • Token过期处理:后端要配置Token的过期时间,前端在收到401/403响应时,要清除存储的token并跳转到注册页。
  • 后端安全配置:确保你的Spring Security配置正确,比如允许OPTIONS请求(如果用CORS),配置JWT过滤器从请求头(情况1)或Cookie(情况2)中提取Token进行认证。

备注:内容来源于stack exchange,提问作者PavelPavlik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.16 11:19:50