Angular发起API请求后ASP.NET Core的Session为null问题求解
问题核心原因
- Angular的HttpClient默认不会自动携带跨域/代理请求的Cookie,导致后端无法匹配到对应的Session
- 后端中间件顺序错误,Cookie策略未在Session之前生效,导致Session Cookie处理异常
- Session的SameSite配置不合理可能导致浏览器拦截Cookie
修复步骤
后端调整
- 修正
Configure方法的中间件顺序,将UseCookiePolicy移到UseSession之前,确保Cookie配置先生效:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseHttpsRedirection(); app.UseCookiePolicy(); // 调整到UseSession之前 app.UseSession(); app.UseRouting(); // 全局CORS策略保留原有配置即可 app.UseCors(x => x .AllowAnyMethod() .AllowAnyHeader() .SetIsOriginAllowed(origin => true) .AllowCredentials()); app.UseAuthentication(); app.UseAuthorization(); app.UseMiddleware<ErrorHandlerMiddleware>(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
- 调整Session的SameSite配置,避免浏览器拦截Cookie:
services.AddSession(option => { option.Cookie.IsEssential = true; option.Cookie.Name = "Survey-Service"; option.Cookie.HttpOnly = true; option.IdleTimeout = TimeSpan.FromMinutes(1); // 本地开发用Lax即可,生产环境跨域部署请改为SameSiteMode.None,同时新增option.Cookie.Secure = true option.Cookie.SameSite = SameSiteMode.Lax; });
Angular端调整
所有HTTP请求需要明确开启withCredentials配置,才会自动携带Cookie。以你提供的get方法为例,修改后代码如下:
public get<E>(url: string, options?, mapper?): Observable<E> { // 合并请求配置,强制开启withCredentials const finalOptions = { ...options, withCredentials: true }; return this.httpClient .get(url, finalOptions) .pipe( map(json => { return mapper ? mapper(json) : json; }), catchError((errorRes: HttpErrorResponse) => { if (errorRes.error['dataexception']!=null && errorRes.error['dataexception']['data'] != null) { var listofExceptions = Object.values(errorRes.error['dataexception']['data']); if (listofExceptions.length > 0) { listofExceptions.forEach(element => { this.extension.showNotification(ColorState.error, element); }); } } else if (errorRes != null && errorRes.error != null && errorRes.error['message'] != null) { this.extension.showNotification(ColorState.error, errorRes.error['message']); } else { this.extension.showNotification(ColorState.error, this.errorMessage); } if (errorRes.status === 500 && errorRes.error !== null && errorRes.error.code === 401) { return; } return throwError(errorRes.error || 'Server error'); }), finalize(() => { // 隐藏加载动画 }) ); }
注意post、put、delete等其他请求方法也需要添加同样的withCredentials: true配置。
修改完成后可以通过浏览器开发者工具的Network面板,检查非登录请求的请求头中是否携带了Survey-Service对应的Cookie,确认配置生效。
内容的提问来源于stack exchange,提问作者Taha Yazdani
相关产品推荐
相关产品推荐

