.NET 7 Web API在Chrome/Edge中无法设置Refresh Token Cookie问题
我使用C#和.NET 7开发Web API,其中一个端点负责生成并设置Refresh Token Cookie。在Chrome和Edge的Swagger UI中登录时,Cookie无法被设置,但用PostMan测试接口却能正常设置,请问可能是什么原因?
可能的原因及解决方向
- SameSite Cookie属性缺失:.NET默认的CookieOptions未设置SameSite属性,浏览器在Swagger的同源/跨域场景下会限制这类Cookie,而PostMan默认不严格校验该属性。建议修改CookieOptions:
开发环境若使用HTTP,可改用var cookieOptions = new CookieOptions { HttpOnly = true, Expires = refreshToken.Expires, SameSite = SameSiteMode.None, // 跨域场景下使用None,需配合Secure=true Secure = true // 生产环境必须开启,开发环境可根据情况调整 };SameSiteMode.Lax避免浏览器限制。 - Swagger UI未启用Cookie携带:Swagger默认不会自动携带Cookie到请求中,需在Swagger配置里开启
withCredentials。在Program.cs中添加:app.UseSwaggerUI(options => { options.ConfigObject.AdditionalItems.Add("withCredentials", true); }); - 浏览器Cookie限制触发:频繁测试设置Cookie可能触发浏览器的Cookie配额限制,导致无法正常写入。(补充案例:重启电脑后问题解决,供开发者参考)
- HttpOnly Cookie的可见性误解:HttpOnly类型的Cookie无法在浏览器开发者工具的Application面板中直接查看,但不代表未设置。可通过后续的Refresh Token请求检查是否携带该Cookie来验证。
相关代码示例
Refresh Token服务方法
private const string RefreshTokenCookieName = "refresh-token"; // 构造函数及其他方法已省略 public RefreshToken GenerateRefreshToken() { var refreshToken = new RefreshToken { Token = Convert.ToBase64String(RandomNumberGenerator.GetBytes(64)), Expires = DateTime.UtcNow.AddDays(7) }; return refreshToken; } public void SetRefreshToken(RefreshToken refreshToken, User user) { var cookieOptions = new CookieOptions { HttpOnly = true, Expires = refreshToken.Expires, }; _httpContextAccessor.HttpContext?.Response.Cookies.Append(RefreshTokenCookieName, refreshToken.Token, cookieOptions); user.RefreshToken = refreshToken.Token; user.RefreshTokenCreated = refreshToken.DateTimeCreated; user.RefreshTokenExpires = refreshToken.Expires; } public string GetRefreshTokenCookie() { return _httpContextAccessor.HttpContext?.Request.Cookies[RefreshTokenCookieName]!; }
Refresh Token处理器代码
public async Task<string> Handle(RefreshTokenQuery request, CancellationToken cancellationToken) { await Task.CompletedTask; var refreshToken = _jwtTokenService.GetRefreshTokenCookie(); var user = _userRepository.GetUserByUsername(request.Username); if (!user!.RefreshToken.Equals(refreshToken)) { throw new RefreshTokenInvalidException(); } else if (user!.RefreshTokenExpires < DateTime.UtcNow) { throw new RefreshTokenExpiredException(); } else { var token = _jwtTokenService.GenerateToken(user); var newRefreshToken = _jwtTokenService.GenerateRefreshToken(); _jwtTokenService.SetRefreshToken(newRefreshToken, user); return token; } }
内容的提问来源于stack exchange,提问作者Martin Rohwedder
相关产品推荐
相关产品推荐

