Twitch OAuth2授权成功后无法重定向问题求助
核心原因分析
1. 自定义回调Controller绕过了Spring Security的OAuth2流程
你手动实现了/oauth2/code/twitch的回调接口,没有让Spring Security的OAuth2客户端自动处理该回调。Twitch授权完成后直接请求到你的自定义Controller,完全跳过了Spring Security的oauth2Login过滤器链,因此Security配置中设置的defaultSuccessUrl根本不会被触发。而Google是Spring Security默认支持的提供商,其回调由框架自动处理,所以重定向正常。
2. 回调接口返回格式错误
handleTwitchCallback方法返回ResponseEntity.ok().body("")是200 OK响应,浏览器会直接显示空内容,不会触发重定向。只有返回3xx状态码的重定向响应,浏览器才会跳转到指定页面。
3. 重复调用oauth2Login()导致配置覆盖
Security配置中连续两次调用.oauth2Login()是错误的,Spring Security的配置是覆盖式的,第二次调用会完全替换第一次的配置。不过这不是Twitch重定向失效的主要原因,因为Google的回调由框架自动处理,不受该错误配置影响。
解决方案
方案一:移除自定义Controller,让Spring Security自动处理Twitch登录
既然已经在配置文件中正确配置了Twitch的客户端和提供商信息,Spring Security可以自动完成授权码交换、令牌获取、用户信息拉取的全流程,无需自定义Controller。
- 删除自定义的
OAuth2Controller - 修改Security配置为统一的
oauth2Login配置:
@Configuration public class OAuth2SecurityConfig { @Bean public SecurityFilterChain oauth2SecurityFilterChain(HttpSecurity http) throws Exception { http .oauth2Login(oauth2 -> oauth2 .defaultSuccessUrl("http://localhost:4200/oauthsuccess", true) .failureUrl("http://localhost:4200/oauthfailure") ); return http.build(); } }
这样所有配置的OAuth2客户端(Google、Twitch)都会使用统一的成功/失败重定向规则。
方案二:保留自定义回调逻辑,手动实现重定向
如果需要在回调中执行自定义业务逻辑(比如存储用户信息、记录日志等),可以在处理完逻辑后手动返回重定向响应:
- 修改
handleTwitchCallback方法,返回302重定向响应:
@GetMapping("/twitch") public ResponseEntity<Void> handleTwitchCallback(@RequestParam("code") String authorizationCode) { // 原有业务逻辑不变 System.out.println("Authorization Code: " + authorizationCode); String accessToken = getAccessToken(authorizationCode); System.out.println("Access Token: " + accessToken); ResponseEntity<String> userInfoResponse = getUserInfo(accessToken); System.out.println("User Info: " + userInfoResponse.getBody()); // 手动构建重定向响应 HttpHeaders headers = new HttpHeaders(); headers.setLocation(URI.create("http://localhost:4200/oauthsuccess")); return new ResponseEntity<>(headers, HttpStatus.FOUND); }
- 修改Security配置,允许匿名访问Twitch回调路径:
@Configuration public class OAuth2SecurityConfig { @Bean public SecurityFilterChain oauth2SecurityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .requestMatchers("/oauth2/code/twitch").permitAll() .anyRequest().authenticated() ) .oauth2Login(oauth2 -> oauth2 .defaultSuccessUrl("http://localhost:4200/oauthsuccess", true) .failureUrl("http://localhost:4200/oauthfailure") ); return http.build(); } }
内容的提问来源于stack exchange,提问作者Jujules

