ASP.NET MVC Service API与Web UI调用时Session丢失问题求助
解决方法
根因说明
Session依赖ASP.NET_SessionIdCookie识别用户身份,你通过Angular调用时出现Session丢失,本质是跨域场景下浏览器默认不会携带目标站点的Cookie,导致后端无法识别请求所属的会话。
分步修复
1. 后端配置CORS允许凭证传输
首先安装Microsoft.AspNet.WebApi.CorsNuGet包,然后在WebApiConfig中开启CORS配置,必须指定具体允许的前端源(不能用通配符*),同时开启凭证支持:
using System.Web.Http; using System.Web.Http.Cors; public static class WebApiConfig { public static void Register(HttpConfiguration config) { // 替换为你的Angular WebUI实际访问地址,开发环境默认是http://localhost:4200 var corsAttr = new EnableCorsAttribute("http://localhost:4200", "*", "*") { SupportsCredentials = true }; config.EnableCors(corsAttr); // 保留你原有的其他WebAPI配置 } }
2. 前端Angular请求携带凭证
所有调用Service API的请求都需要配置withCredentials: true,通知浏览器携带跨域Cookie:
单请求配置示例:
import { HttpClient } from '@angular/common/http'; constructor(private http: HttpClient) {} // 调用setContext接口 setContext() { this.http.post('http://localhost/ServiceAPI/api/user/setContext', {}, { withCredentials: true }).subscribe(); } // 调用getContext接口 getContext() { this.http.get('http://localhost/ServiceAPI/api/user/getContext', { withCredentials: true }).subscribe(res => console.log(res)); }
全局拦截器统一配置(推荐):
如果需要所有请求都自动携带凭证,新增拦截器统一配置即可,不需要每个请求单独加参数:
import { Injectable } from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http'; import { Observable } from 'rxjs'; @Injectable() export class CredentialsInterceptor implements HttpInterceptor { intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { const modifiedReq = request.clone({ withCredentials: true }); return next.handle(modifiedReq); } }
然后在AppModule的providers中注册拦截器:
providers: [ { provide: HTTP_INTERCEPTORS, useClass: CredentialsInterceptor, multi: true } ]
3. 适配浏览器SameSite Cookie规则
新版本浏览器默认会拦截跨域请求中SameSite属性不为None的Cookie,需要在后端web.config中配置Session Cookie的SameSite属性:
<system.web> <!-- 开发环境可将requireSSL设为false,生产环境必须设为true且使用HTTPS --> <httpCookies sameSite="None" requireSSL="false" /> <!-- 如果你的Session Cookie默认路径限制在/ServiceAPI下,添加cookiePath="/"放开路径限制 --> <sessionState mode="SQLServer" cookiePath="/" /> </system.web>
验证方法
发起setContext请求后,打开浏览器调试工具的网络面板,查看响应头是否存在Set-Cookie: ASP.NET_SessionId=xxx的返回;后续发起getContext请求时,查看请求头是否携带了对应的ASP.NET_SessionIdCookie,携带正常则Session不会丢失。
内容的提问来源于stack exchange,提问作者StackUser
相关产品推荐
相关产品推荐

