Spring Security下2FA验证返回HTML,Angular解析JSON报错
问题分析与解决方案
问题根源
你遇到的HttpErrorResponse错误核心原因是:前端请求最终收到了HTML页面而非预期的JSON响应。错误日志里的请求URL是http://localhost:8080/login,但你的前端代码调用的是/api/v1/login/validateOtp接口,说明存在请求重定向或意外的表单提交行为,导致Spring Security返回了默认的HTML登录页面,Angular尝试将HTML解析为JSON时抛出语法错误。
Postman测试正常是因为它直接调用正确的API接口,没有触发多余的浏览器默认行为。
具体解决方案
1. 阻止浏览器默认表单提交行为(最可能的直接原因)
新手在Angular中使用<form>标签时,容易忽略浏览器的默认表单提交逻辑:点击提交按钮时,浏览器会自动发起传统的POST请求(目标URL可能是当前页面或错误的/login),这个请求返回的是Spring Security的HTML登录页面,而非你的API接口的JSON响应。
修改two-factor.component.ts的onSubmit方法,添加事件阻止逻辑:
onSubmit(event: Event) { event.preventDefault(); // 关键:阻止浏览器默认提交行为 this.userService.validateOTP(this.otp).subscribe( () => { console.log('OTP验证成功'); this.router.navigate(['/你的目标页面']); // 验证成功后跳转页面 }, error => { console.error('OTP验证失败:', error); // 这里可以添加错误提示(比如弹窗显示验证码错误) } ); }
同时修改对应的HTML模板,确保事件绑定正确:
<form (ngSubmit)="onSubmit($event)"> <input type="text" [(ngModel)]="otp.otp" name="otp" placeholder="输入验证码" /> <input type="hidden" [(ngModel)]="otp.sessionId" name="sessionId" /> <button type="submit">提交</button> </form>
2. 移除Spring Security中不必要的formLogin配置
你的WebSecurityConfig中启用了.formLogin(),但前后端分离的API服务不需要Spring Security提供的默认HTML登录页面,这个配置可能导致意外的重定向。修改配置移除该项:
@Override public void configure(HttpSecurity http) throws Exception { http.cors().and().csrf().disable() .authorizeRequests() .antMatchers("/**").permitAll() // 生产环境请根据实际权限调整 .anyRequest().authenticated() .and() .httpBasic(); // 移除 .formLogin() 配置,避免生成默认HTML登录页面 }
3. 检查sessionId的传递是否正确
确保otp.sessionId已经从登录接口的响应中获取并正确赋值,若sessionId为空,后端验证逻辑可能触发认证拦截,导致重定向到登录页面。
内容的提问来源于stack exchange,提问作者burak.gng
相关产品推荐
相关产品推荐

