React JS访问Spring Security保护的API鉴权实现问题求助
React + Spring Security 会话鉴权问题解决方案
核心问题说明
你不需要手动读取Set-Cookie响应头获取JSESSIONID,带HttpOnly属性的Cookie本身就禁止JavaScript读取,这是浏览器的安全机制,目的是防范XSS攻击窃取会话凭证。只要配置正确,浏览器会自动存储JSESSIONID,并在后续请求中自动携带。
前端代码修改
你当前的核心问题是Spring Security的formLogin默认仅接收application/x-www-form-urlencoded格式的请求参数,而你的代码提交的是JSON格式参数,导致登录逻辑本身就执行失败,自然无法拿到正确的会话Cookie。
修改步骤如下:
- 安装qs用于序列化表单参数:
npm install qs - 修改登录逻辑代码:
import qs from 'qs'; import axios from 'axios'; // 全局配置跨域请求携带凭据,所有发往后端的请求都会自动带Cookie axios.defaults.withCredentials = true; // 全局配置POST请求默认使用表单格式 axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; const onSubmitAuthenticateButton = (e) => { e.preventDefault(); const loginUrl = 'http://myserver:8080/login'; // 序列化参数为表单格式,匹配Spring Security默认参数要求 const loginParams = qs.stringify({ username: username, password: password }); axios.post(loginUrl, loginParams) .then(res => { console.log('登录成功,JSESSIONID已由浏览器自动存储'); // 后续访问受保护接口直接发请求即可,不需要手动加Cookie return axios.get('http://myserver:8080/你的受保护接口路径'); }) .then(protectedRes => { console.log('受保护接口返回数据:', protectedRes.data); }) .catch(err => console.log('请求失败:', err.message)); }
后端配置优化
你现有的配置大部分正确,仅需做两处小调整:
- WebMvcConfig中
exposedHeaders("Set-Cookie")可以删除,该配置对HttpOnly的Cookie无效,不会影响功能 - 为了避免Spring Security和Spring MVC的CORS配置冲突,可以在WebSecurityConfig中显式注入CORS配置
修改后的WebSecurityConfig完整代码:
@Configuration public class WebSecurityConfig extends WebSecurityConfigurerAdapter{ private CustomAuthenticationProvider customAuthProvider; public WebSecurityConfig(CustomAuthenticationProvider customAuthProvider) { super(); this.customAuthProvider = customAuthProvider; } @Bean CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOrigins(Arrays.asList("http://myserver:3000")); configuration.setAllowedMethods(Arrays.asList("GET", "POST", "OPTIONS")); configuration.setAllowCredentials(true); configuration.setMaxAge(3600L); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; } @Override protected void configure(HttpSecurity http) throws Exception { http .cors(cors -> cors.configurationSource(corsConfigurationSource())) .and() .csrf().disable() .authorizeRequests() .anyRequest().fullyAuthenticated() .and() .formLogin(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(customAuthProvider); } }
配置完成后即可正常实现会话鉴权,不需要手动处理Cookie的读取和携带。
内容的提问来源于stack exchange,提问作者Himanshu
相关产品推荐
相关产品推荐

