基于Session的SpringBoot认证跨域Cookie不被接受问题求助
问题描述
- 自学开发全栈项目,后端基于SpringBoot构建,采用Session认证方式,已配置可接受源,但存在以下问题:
- 后端以Docker镜像运行在树莓派上,IP为
192.168.x.x:8081,Postman测试所有接口正常; - 使用VS Code的live server或live preview访问前端时,登录/注册功能正常,但成功跳转至仪表盘后发起的GET请求始终返回401状态码;
- 浏览器开发者工具显示SessionID对应的Cookie标注有"!",提示该Cookie为跨站来源不被接受;
- 曾尝试将所有服务部署在笔记本的Docker中,但因网络差异,跨域问题依旧存在。
相关配置代码
Security配置
package de.ExpenseTracker.security; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.annotation.web.configurers.LogoutConfigurer; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; @Configuration public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .cors(Customizer.withDefaults()) .csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests(auth -> auth .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() .requestMatchers("/users/**").permitAll() .anyRequest().authenticated() ) .formLogin(form -> form .loginProcessingUrl("/users/login") .successHandler((req, res, auth) -> res.setStatus(200)) .failureHandler((req, res, ex) -> res.sendError(401)) ) .exceptionHandling(e -> e .authenticationEntryPoint((req, res, ex) -> res.sendError(401)) ) .logout(LogoutConfigurer::permitAll); return http.build(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
Cors配置
package de.ExpenseTracker.security; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfigurationSource; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import java.util.List; @Configuration public class CorsConfig { @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration config = new CorsConfiguration(); config.setAllowedOrigins(List.of( "http://127.0.0.1:3000", "http://localhost:3000", "http://192.168.178.44:3000", "http://127.0.0.1:5500", "http://192.168.178.31:5500" )); config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS")); config.setAllowedHeaders(List.of("*")); config.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); return source; } }
dev.properties文件
spring.datasource.url=jdbc:postgresql://192.168.x.x:5432/expensetracker_test spring.datasource.username=e spring.datasource.password=@ spring.jpa.hibernate.ddl-auto=update server.servlet.session.cookie.same-site=Lax
解决方案
1. 调整Cookie的SameSite与安全属性
当前SameSite=Lax在跨域场景下限制较严,且缺少域名绑定,修改dev.properties:
# 允许跨站发送Cookie server.servlet.session.cookie.same-site=None # 开发环境(HTTP)下关闭secure要求,避免浏览器拒绝Cookie server.servlet.session.cookie.secure=false # 绑定Cookie到树莓派的局域网IP,确保前端能正确识别并携带 server.servlet.session.cookie.domain=192.168.x.x
注意:如果使用Chrome浏览器,可能需要开启允许不安全Cookie的设置:打开
chrome://flags/#cookies-without-same-site-must-be-secure,设置为Disabled后重启浏览器。
2. 确认CORS允许的源包含前端实际地址
检查VS Code live server/preview的实际访问地址(比如浏览器地址栏的http://xxx:5500),确保该地址已添加到CorsConfig的setAllowedOrigins列表中。测试阶段可以临时用List.of("*"),但生产环境必须指定具体域名。
3. 前端请求开启Credentials携带
确保前端发起请求时配置了携带Cookie:
- Axios:
axios.defaults.withCredentials = true - 原生Fetch:
fetch('后端接口地址', { credentials: 'include' })
只有前端开启这个配置,后端设置的AllowCredentials=true才会生效,Session Cookie才能被正确携带到后续请求中。
4. 统一局域网域名(可选)
修改本地hosts文件(Windows在C:\Windows\System32\drivers\etc\hosts,Linux/macOS在/etc/hosts),添加映射:
192.168.x.x expensetracker.local
然后前端用http://expensetracker.local:5500访问,后端用http://expensetracker.local:8081,这样属于同域名跨端口,SameSite设为Lax也能正常工作,从根源避免跨域问题。
内容的提问来源于stack exchange,提问作者joel.
相关产品推荐
相关产品推荐

