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

Spring Boot Todo应用登录后按用户ID重定向至/todo/{id}问题求助

解决Spring Boot登录后动态重定向至带用户ID的待办页面问题

要实现登录后根据用户ID重定向到/todo/{id},不能直接通过defaultSuccessUrl配置占位符路径,因为Spring Security无法在这里动态填充用户参数。需要通过自定义登录成功处理器来实现动态重定向逻辑,步骤如下:

1. 自定义AuthenticationSuccessHandler

创建处理器类,在登录成功后获取当前用户ID并构造重定向URL:

import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
        // 从认证信息中获取当前登录的User对象
        User currentUser = (User) authentication.getPrincipal();
        // 构造目标重定向路径
        String targetUrl = "/todo/" + currentUser.getId();
        // 执行重定向
        response.sendRedirect(targetUrl);
    }
}

2. 修改SecurityConfig配置

替换原有的defaultSuccessUrl,使用自定义的成功处理器:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Autowired
    private UserRepository userRepository;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.formLogin(login -> login
                .loginPage("/login")
                .loginProcessingUrl("/login")
                // 使用自定义登录成功处理器
                .successHandler(new CustomAuthenticationSuccessHandler())
                .failureUrl("/login?error")
                .permitAll())
                .authorizeHttpRequests(authz -> authz
                        .mvcMatchers("/css/**").permitAll()
                        .mvcMatchers("/signup").permitAll()
                        .anyRequest().authenticated()
                )
                .authenticationProvider(authenticationProvider());
        
        http.logout().permitAll();
        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public AuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(customUserDetailsService());
        authProvider.setPasswordEncoder(passwordEncoder());
        return authProvider;
    }

    @Bean
    public UserDetailsService customUserDetailsService() {
        return email -> {
            // 根据邮箱查询用户,替换为你的实际查询逻辑
            User user = userRepository.findByEmail(email)
                    .orElseThrow(() -> new UsernameNotFoundException("用户不存在:" + email));
            return user;
        };
    }
}

3. 让User类实现UserDetails接口

Spring Security需要通过UserDetails获取用户认证信息,因此需让你的User实体实现该接口:

@Entity
@Table(name = "users")
public class User implements UserDetails {
    // 原有字段和getter/setter保持不变

    // 实现UserDetails接口的方法
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        // 根据用户的authority字段返回权限列表
        return Collections.singletonList(new SimpleGrantedAuthority(this.getAuthority()));
    }

    @Override
    public String getUsername() {
        // 使用邮箱作为登录用户名
        return this.getEmail();
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}

关键说明

  • defaultSuccessUrl只能配置固定路径,无法动态注入用户ID这类运行时参数,因此必须通过自定义AuthenticationSuccessHandler实现动态重定向。
  • 确保UserRepository实现了findByEmail方法,能正确从数据库查询到包含ID的User对象,这样才能在成功处理器中获取到用户ID。

内容的提问来源于stack exchange,提问作者funeral of tech

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 18:48:19