Spring Boot无法接收React传递的Jwt Cookie问题排查
我在Spring Boot后端实现了JwtService用于设置携带refresh token的Cookie,代码如下:
private void addJwtCookie(HttpServletResponse response, String refreshToken) { Cookie cookie = new Cookie("jwt", refreshToken); cookie.setHttpOnly(true); cookie.setMaxAge((int) refreshTokenExpiration); cookie.setSecure(true); // This has to be set to work for all endpoints cookie.setPath("/"); response.addCookie(cookie); }
CORS配置如下:
@Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOrigins(List.of("http://localhost:3000")); configuration.setAllowedMethods(List.of("GET", "POST")); configuration.setAllowedHeaders(List.of("Content-Type")); configuration.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; }
React端请求代码:
const signIn = async (signInRequest: SignInRequest) => { try { const res = await axios.post(`${process.env.REACT_APP_API}/api/v1/auth/sign-in`, signInRequest, { withCredentials: true }) setUser(res.data) } catch (err) { } } const refresh = async () => { const res = await axios.post(`${process.env.REACT_APP_API}/api/v1/auth/refresh-token`, { withCredentials: true }) if (res.data) { setUser(res.data) } }
调用signIn接口后,Chrome DevTools中可以看到Cookie,但调用refresh-token接口时,Spring Boot端通过Cookie[] cookies = request.getCookies();获取到的Cookie数组为空。请问如何让React正确传递Cookie到Spring Boot后端?
修正Axios请求的配置位置
你的refresh接口请求写法错误:axios.post的第二个参数是请求体,第三个参数才是配置项。你把withCredentials放到了请求体参数里,导致浏览器没有收到携带Cookie的指令。
修复后的代码:const refresh = async () => { const res = await axios.post( `${process.env.REACT_APP_API}/api/v1/auth/refresh-token`, {}, // 后端不需要请求体时传空对象 { withCredentials: true } ) if (res.data) { setUser(res.data) } }检查
Secure属性的适配场景
你设置了cookie.setSecure(true),该属性要求Cookie仅通过HTTPS传输。如果本地开发后端用的是HTTP协议(比如http://localhost:8080),浏览器会拒绝在HTTP请求中携带这个Cookie,导致后端无法获取。
处理方式:- 本地开发时临时注释掉
setSecure(true); - 或者根据环境动态设置:
// 假设env是Spring的Environment对象 cookie.setSecure(Arrays.asList(env.getActiveProfiles()).contains("prod"));
- 本地开发时临时注释掉
配置Cookie的
SameSite属性
默认的SameSite=Lax规则可能会在跨域POST请求中拦截Cookie。生产环境下(HTTPS)可以设置为SameSite=None(必须配合Secure属性);本地HTTP环境下可以设置为Lax或者不设置(使用默认值)。
添加代码:// 生产环境HTTPS下使用 cookie.setSameSite("None"); // 本地HTTP环境可以用这个 // cookie.setSameSite("Lax");确保请求域名完全一致
确认React前端请求的后端地址(process.env.REACT_APP_API)和设置Cookie的后端域名完全匹配,比如不能前端用http://localhost:8080,后端Cookie设置在http://127.0.0.1:8080,否则浏览器会判定为不同域名,不携带Cookie。
内容的提问来源于stack exchange,提问作者m_jdm35

