You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.06 19:04:50