ASP.NET登录后如何将accessToken、userId传递到其他Action调用用户信息API
实现方案
第一步:定义登录响应实体,反序列化接口返回值
首先你要先创建一个实体类映射登录接口的返回结构,同时修正你现有代码中遗漏await的问题(ReadAsStringAsync是异步方法,不加await拿不到正确的返回内容):
// 定义登录响应实体 public class LoginApiResponse { public string AccessToken { get; set; } public string AccessTokenExpireAt { get; set; } public string RefreshToken { get; set; } public string UserID { get; set; } }
然后在你拿到结果的位置补充反序列化逻辑:
// 原有代码修正,加await var result = await response.Content.ReadAsStringAsync(); // 反序列化,这里用System.Text.Json为例,用Newtonsoft.Json同理 var loginResult = System.Text.Json.JsonSerializer.Deserialize<LoginApiResponse>(result);
第二步:选择存储方案传递凭证
不要直接通过URL参数传递accessToken,会泄露敏感信息,推荐两种安全的存储方案:
方案1:服务端Session存储(推荐,安全性更高)
首先需要在你的ASP.NET Core项目中开启Session配置:
- 在
Program.cs中添加Session服务配置:
builder.Services.AddSession(options => { // 设置Session过期时间,和accessToken过期时间保持一致即可 options.IdleTimeout = TimeSpan.FromMinutes(30); options.Cookie.HttpOnly = true; options.Cookie.IsEssential = true; options.Cookie.SecurePolicy = CookieSecurePolicy.Always; // 生产环境必须开启 }); // 注意要在UseRouting和UseAuthorization之间加UseSession app.UseSession();
- 登录成功后存储凭证,并重定向到个人资料页:
// 反序列化拿到loginResult后存储到Session HttpContext.Session.SetString("AccessToken", loginResult.AccessToken); HttpContext.Session.SetString("UserId", loginResult.UserID); // 重定向到Profile Action return RedirectToAction("Profile", "User");
方案2:加密Cookie存储(适合无状态服务场景)
如果不想用服务端Session,可将凭证加密后存入HttpOnly Cookie:
// 存储到Cookie,设置安全属性 CookieOptions cookieOptions = new CookieOptions { HttpOnly = true, Secure = true, SameSite = SameSiteMode.Strict, Expires = DateTime.Parse(loginResult.AccessTokenExpireAt) }; Response.Cookies.Append("AccessToken", loginResult.AccessToken, cookieOptions); Response.Cookies.Append("UserId", loginResult.UserID, cookieOptions); return RedirectToAction("Profile", "User");
第三步:在个人资料Action中调用用户信息API
以Session存储为例,在Profile Action中取出凭证后调用接口:
public async Task<IActionResult> Profile() { // 校验凭证是否存在 var accessToken = HttpContext.Session.GetString("AccessToken"); var userId = HttpContext.Session.GetString("UserId"); if (string.IsNullOrEmpty(accessToken) || string.IsNullOrEmpty(userId)) { // 凭证过期或不存在,跳回登录页 return RedirectToAction("Index", "Login"); } // 调用用户信息API using var client = new HttpClient(); string userInfoUrl = "你的用户信息API端点"; // 把accessToken放到请求头Authorization中 client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); var response = await client.GetAsync(userInfoUrl); if (response.IsSuccessStatusCode) { // 自己定义UserInfoModel映射接口返回的firstname、邮箱等字段 var userInfo = await response.Content.ReadFromJsonAsync<UserInfoModel>(); return View(userInfo); } // 接口调用失败,比如token过期,可以用refreshToken刷新后重试,或者跳回登录 return RedirectToAction("Index", "Login"); }
注意事项
accessToken属于敏感信息,禁止明文传递、禁止存储到前端本地存储(localStorage/sessionStorage),容易被XSS攻击盗取- 生产环境必须开启Cookie的Secure属性,仅允许HTTPS传输
- 可以在
accessToken过期时,用存储的refreshToken调用刷新接口获取新的凭证,避免用户重复登录
内容的提问来源于stack exchange,提问作者Sami In
相关产品推荐
相关产品推荐

