SpringBoot+Angular开发环境跨端口共享Session Cookie配置咨询
问题根源
浏览器的同源策略把localhost:8080和localhost:4200判定为不同源——哪怕域名都是localhost,端口不同就会阻止Cookie跨端口携带。另外SpringBoot默认的Cookie未配置SameSite和Domain属性,也会让浏览器拒绝在跨端口请求里携带Cookie。
一、SpringBoot后端配置调整
1. 调整Cookie属性
修改Cookie配置,让浏览器允许跨端口携带:
- 设置
Domain=.localhost:让Cookie在localhost所有端口生效 - 把
Path设为/:确保Cookie在所有路径可用 - 添加
SameSite=None:允许跨站点(含同域名不同端口)携带Cookie,开发环境用HTTP时需关闭Secure属性(生产环境必须开启)
用配置类实现:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.session.web.http.CookieSerializer; import org.springframework.session.web.http.DefaultCookieSerializer; @Configuration public class CookieConfig { @Bean public CookieSerializer cookieSerializer() { DefaultCookieSerializer serializer = new DefaultCookieSerializer(); serializer.setDomainName(".localhost"); serializer.setCookiePath("/"); serializer.setSameSite("None"); serializer.setUseSecureCookie(false); // 开发环境HTTP下关闭,生产必须开启 return serializer; } }
2. 配置CORS允许凭证
CORS必须开启allowCredentials,否则浏览器不会发送Cookie:
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**") .allowedOrigins("http://localhost:4200") .allowedMethods("GET", "POST", "PUT", "DELETE") .allowCredentials(true); // 关键:允许携带Cookie等凭证 } }
二、Angular前端配置调整
请求必须设置withCredentials: true,不然浏览器不会携带Cookie:
1. 全局拦截器(推荐)
给所有请求自动添加withCredentials,在app.module.ts中配置:
import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http'; @Injectable() export class CredentialsInterceptor implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler) { return next.handle(req.clone({ withCredentials: true })); } } @NgModule({ providers: [ { provide: HTTP_INTERCEPTORS, useClass: CredentialsInterceptor, multi: true } ] }) export class AppModule {}
2. 单个请求设置
如果只需要给特定请求添加:
import { HttpClient } from '@angular/common/http'; constructor(private http: HttpClient) {} callBackendService() { this.http.get('/api/service', { withCredentials: true }) .subscribe(res => { // 处理响应 }); }
三、更省心的开发环境方案:Angular代理
直接用Angular的代理把前端请求转发到后端,浏览器会认为是同域请求,Cookie自动携带,无需修改跨域和Cookie配置:
- 在项目根目录创建
proxy.conf.json:
{ "/api": { "target": "http://localhost:8080", "secure": false, "changeOrigin": true } }
- 修改
angular.json里的启动配置,指定代理文件:
"serve": { "builder": "@angular-devkit/build-angular:dev-server", "options": { "browserTarget": "你的项目名:build", "proxyConfig": "proxy.conf.json" } }
- 前端请求直接写
/api/service,不用带http://localhost:8080,代理会自动转发到后端。
四、生产环境注意事项
开发环境的配置别直接搬去生产:
- 生产同域名下,
SameSite设为Lax或Strict更安全,无需设置为None - 生产必须开启
Secure属性,确保Cookie只在HTTPS传输 Domain设为实际业务域名,比如.yourdomain.com
内容的提问来源于stack exchange,提问作者user60108
相关产品推荐
相关产品推荐

