ASP.Net Core2 WebAPI创建的Cookie未被Angular5请求发送,求往返示例
嘿,我来帮你解决这个Cookie不回传的问题!这种情况十有八九是跨域(CORS)配置没到位,毕竟Angular SPA和WebAPI通常会跑在localhost的不同端口上,浏览器的同源策略会拦着Cookie自动跟着请求走。下面给你一套完整的Server->Client->Server往返流程示例,一步步来:
第一步:配置ASP.NET Core WebAPI的CORS策略
要让浏览器允许携带Cookie,CORS必须开启AllowCredentials = true,而且不能用通配符*指定Origin,得写死Angular SPA的具体地址(比如默认的http://localhost:4200)。在Startup.cs里修改配置:
public void ConfigureServices(IServiceCollection services) { // 配置CORS策略,允许本地Angular应用的请求 services.AddCors(options => { options.AddPolicy("AllowLocalAngular", builder => builder.WithOrigins("http://localhost:4200") .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials()); // 核心:允许携带凭证(Cookie) }); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } // 必须在UseMvc之前启用CORS,否则不生效 app.UseCors("AllowLocalAngular"); app.UseMvc(); }
你的控制器代码基础没问题,但有几个细节需要调整,尤其是跨域场景下的SameSite属性,Chrome 80+对这个属性的校验很严格。修改后的控制器:
public class TestController : ControllerBase { [HttpGet, Route("api/[controller]/test")] public async Task<IActionResult> Get() { Response.Cookies.Append("testcookie", "testvalue", new CookieOptions { Path = "/", // localhost跨端口时可以去掉Domain设置,浏览器会自动匹配当前域名 // Domain = "localhost", Expires = DateTime.UtcNow.AddHours(6), HttpOnly = false, // 如果不需要Angular读取Cookie,建议设为true更安全 Secure = false, // 本地http环境必须设为false,https环境才设为true SameSite = SameSiteMode.None // 跨域场景必须设置,否则浏览器可能不发送Cookie }); return Ok("Test Ok."); } // 新增一个接口,用来验证后续请求是否携带了Cookie [HttpGet, Route("api/[controller]/check-cookie")] public async Task<IActionResult> CheckCookie() { var cookieValue = Request.Cookies["testcookie"]; return string.IsNullOrEmpty(cookieValue) ? Ok("Cookie not received.") : Ok($"Cookie received successfully: {cookieValue}"); } }
第三步:Angular 5客户端请求代码
Angular发送请求时必须显式设置withCredentials: true,否则浏览器不会主动携带Cookie。先创建一个服务test.service.ts:
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class TestService { // 替换成你的WebAPI实际端口(比如5000) private apiBaseUrl = 'http://localhost:5000/api/test'; constructor(private http: HttpClient) { } // 第一个请求:获取服务器设置的Cookie getCookie(): Promise<string> { return this.http.get(this.apiBaseUrl + '/test', { withCredentials: true }) .toPromise() .then(res => res as string); } // 第二个请求:验证Cookie是否被携带到服务器 verifyCookie(): Promise<string> { return this.http.get(this.apiBaseUrl + '/check-cookie', { withCredentials: true }) .toPromise() .then(res => res as string); } }
然后在组件里调用这两个方法,比如app.component.ts:
import { Component, OnInit } from '@angular/core'; import { TestService } from './test.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { constructor(private testService: TestService) { } ngOnInit() { // 第一步:请求服务器设置Cookie this.testService.getCookie().then(result => { console.log('First request response:', result); // 第二步:立即发送第二个请求,验证Cookie是否被携带 this.testService.verifyCookie().then(verifyResult => { console.log('Cookie verification result:', verifyResult); }); }); } }
完整往返流程说明
Server -> Client:
- Angular客户端发送第一个
GET /api/test/test请求,请求头携带withCredentials: true标记 - WebAPI处理请求后,在响应头里添加
Set-Cookie字段,返回结果 - 浏览器因为CORS策略允许凭证,会将Cookie存储到本地
- Angular客户端发送第一个
Client -> Server:
- Angular客户端发送第二个
GET /api/test/check-cookie请求,同样携带withCredentials: true - 浏览器自动把存储的
testcookie添加到请求头的Cookie字段中 - WebAPI从
Request.Cookies中读取到Cookie值,返回验证成功的结果
- Angular客户端发送第二个
关键注意事项
- 端口匹配:CORS配置里的Origin要和Angular实际运行的端口完全一致(比如Angular跑在4200,就写
http://localhost:4200) - SameSite属性:跨域场景下必须设为
SameSiteMode.None,否则Chrome会拦截Cookie - withCredentials:Angular的每个需要携带Cookie的请求都要开启这个选项
- Secure属性:本地开发用http时必须设为false,上线用https时再改为true
内容的提问来源于stack exchange,提问作者ttugates
相关产品推荐
相关产品推荐

