前后端分离场景下如何保留Spring Security的/login POST接口并移除默认登录页
解决方案
直接修改Spring Security的HttpSecurity配置即可,无需禁用formLogin,核心是替换默认的页面跳转逻辑为前端可识别的JSON响应:
@Override protected void configure(HttpSecurity httpSecurity) throws Exception { httpSecurity .addFilterBefore(authenticationFilter(), UsernamePasswordAuthenticationFilter.class) // 前后端分离场景建议单独配置CORS规则,不要直接禁用 // .cors().disable() .csrf().disable() .authorizeRequests() .antMatchers("/newUser").permitAll() .anyRequest().authenticated() .and() .exceptionHandling() // 未登录请求处理:不跳转默认登录页,返回401状态码,前端捕获后自行跳转登录页 .authenticationEntryPoint((request, response, authException) -> { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.setContentType("application/json;charset=UTF-8"); response.getWriter().write("{\"code\":401,\"msg\":\"未登录,请先认证\"}"); }) .and() .formLogin() // 登录成功处理:不跳转页面,返回成功JSON .successHandler((request, response, authentication) -> { response.setStatus(HttpServletResponse.SC_OK); response.setContentType("application/json;charset=UTF-8"); response.getWriter().write("{\"code\":200,\"msg\":\"登录成功\"}"); }) // 登录失败处理:不跳转错误页,返回失败JSON .failureHandler((request, response, exception) -> { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.setContentType("application/json;charset=UTF-8"); response.getWriter().write("{\"code\":401,\"msg\":\"用户名或密码错误\"}"); }) .permitAll(); }
配置说明
- 保留了formLogin配置,Spring Security原生的
POST /login认证接口、默认认证流程完全不受影响 - 自定义AuthenticationEntryPoint替换默认的302重定向逻辑,不会再返回Spring自动生成的登录页,前端全局捕获401状态码后可自行跳转到前端侧的/login路由
- 自定义登录成功/失败处理器,替换默认的页面跳转逻辑,前端可以直接根据接口返回的JSON处理后续业务
注意事项
- 原配置中的
pertmitAll为拼写错误,正确写法为permitAll - 如果前端登录请求的用户名字段不是默认的
username、密码字段不是默认的password,可在formLogin配置后通过.usernameParameter("自定义字段名")、.passwordParameter("自定义字段名")修改参数映射 - 前后端分离场景建议不要直接禁用CORS,可单独配置CORS规则放行前端域名,避免跨域问题
内容的提问来源于stack exchange,提问作者Johnyb
相关产品推荐
相关产品推荐

