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

Spring Web页面中自动注入登录响应Token并实现登录后重定向的问题

Spring Web页面中自动注入登录响应Token并实现登录后重定向的问题

嗨,我刚接触Spring Security的时候也遇到过类似的问题,咱们一步步来解决:

首先要明确两个核心需求:登录成功后重定向到首页,以及后续跳转页面时自动携带Token无需重复登录。下面是具体的实现方案:


一、修改登录/注册接口,实现重定向+Token存储

你之前的loginSuccess和registerSuccess方法返回的是DTO,没法直接重定向。我们可以把返回类型改成String,同时把登录生成的Token存入HttpOnly Cookie(浏览器会自动在后续请求中携带这个Cookie,无需前端手动处理,还能防止XSS攻击)。

修改登录接口代码

@PostMapping("/auth/loginSuccess")
public String loginUser(ApplicationUser user, HttpServletResponse response) {
    // 调用认证服务获取Token
    LoginResponseDTO loginResponse = authenticationService.loginUser(user.getUsername(), user.getPassword());
    
    // 创建Cookie存储JWT Token
    Cookie jwtCookie = new Cookie("JWT_TOKEN", loginResponse.getToken());
    jwtCookie.setPath("/"); // 设置Cookie作用域为全站
    jwtCookie.setMaxAge(3600); // 设置过期时间为1小时(单位:秒)
    jwtCookie.setHttpOnly(true); // 禁止前端JS读取,提升安全性
    // 如果是HTTPS环境,还可以设置jwtCookie.setSecure(true);
    
    response.addCookie(jwtCookie);
    // 重定向到首页(这里假设你的首页映射是"/"或者"/index")
    return "redirect:/";
}

修改注册接口代码

如果希望注册后自动登录并跳转到首页,可以参考下面的写法:

@PostMapping("/auth/registerSuccess")
public String registerUser(ApplicationUser user, HttpServletResponse response) {
    // 完成用户注册
    ApplicationUser registeredUser = authenticationService.registerUser(user.getUsername(), user.getPassword());
    
    // 注册成功后自动登录,获取Token
    LoginResponseDTO loginResponse = authenticationService.loginUser(registeredUser.getUsername(), user.getPassword());
    
    // 同样将Token存入Cookie
    Cookie jwtCookie = new Cookie("JWT_TOKEN", loginResponse.getToken());
    jwtCookie.setPath("/");
    jwtCookie.setMaxAge(3600);
    jwtCookie.setHttpOnly(true);
    response.addCookie(jwtCookie);
    
    return "redirect:/";
}

二、配置Spring Security,自动从Cookie中提取Token验证

现在Token已经存在Cookie里了,我们需要让Spring Security在每次请求时自动从Cookie中读取Token并完成认证,这样后续跳转页面就不用重复登录了。

1. 编写自定义JWT过滤器

这个过滤器负责从Cookie中提取Token,验证有效性后将用户信息存入SecurityContext:

public class JwtAuthenticationFilter extends OncePerRequestFilter {

    private final JwtTokenProvider jwtTokenProvider;

    public JwtAuthenticationFilter(JwtTokenProvider jwtTokenProvider) {
        this.jwtTokenProvider = jwtTokenProvider;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 从Cookie中获取Token
        String token = getTokenFromCookie(request);
        
        // 验证Token是否有效
        if (token != null && jwtTokenProvider.validateToken(token)) {
            // 获取用户认证信息
            Authentication authentication = jwtTokenProvider.getAuthentication(token);
            // 将认证信息存入SecurityContext,后续接口就能识别当前登录用户
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
        
        filterChain.doFilter(request, response);
    }

    // 从请求Cookie中提取JWT Token
    private String getTokenFromCookie(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if ("JWT_TOKEN".equals(cookie.getName())) {
                    return cookie.getValue();
                }
            }
        }
        return null;
    }
}

2. 配置Spring Security

在Security配置类中添加上面的过滤器,让它在默认的用户名密码过滤器之前执行:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final JwtTokenProvider jwtTokenProvider;

    public SecurityConfig(JwtTokenProvider jwtTokenProvider) {
        this.jwtTokenProvider = jwtTokenProvider;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable() // 如果是前后端分离或不需要CSRF保护可以关闭
            .authorizeRequests()
                // 允许注册、登录相关接口匿名访问
                .antMatchers("/auth/**").permitAll()
                // 其他所有接口需要认证才能访问
                .anyRequest().authenticated()
            .and()
            // 添加自定义JWT过滤器,在默认的用户名密码过滤器之前执行
            .addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider), UsernamePasswordAuthenticationFilter.class);
    }
}

补充说明

  • 这里的JwtTokenProvider是你项目中负责生成、解析JWT的工具类,确保它能正确从Token中解析出用户的权限和身份信息。
  • 如果你的项目不是用JWT,而是用Session认证,其实Spring Security默认就会用Session Cookie来管理登录状态,你只需要调整登录接口的重定向逻辑即可,不需要额外写JWT过滤器。
  • 如果你需要前端手动操作Token(比如发起AJAX请求),可以把Token存入LocalStorage,但HttpOnly Cookie的安全性更高,优先推荐。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 15:13:03