You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 7 Web API在Chrome/Edge中无法设置Refresh Token Cookie问题

问题:Swagger UI无法设置Refresh Token Cookie但PostMan正常的原因及解决

我使用C#和.NET 7开发Web API,其中一个端点负责生成并设置Refresh Token Cookie。在Chrome和Edge的Swagger UI中登录时,Cookie无法被设置,但用PostMan测试接口却能正常设置,请问可能是什么原因?

可能的原因及解决方向

  • SameSite Cookie属性缺失:.NET默认的CookieOptions未设置SameSite属性,浏览器在Swagger的同源/跨域场景下会限制这类Cookie,而PostMan默认不严格校验该属性。建议修改CookieOptions:
    var cookieOptions = new CookieOptions
    {
        HttpOnly = true,
        Expires = refreshToken.Expires,
        SameSite = SameSiteMode.None, // 跨域场景下使用None,需配合Secure=true
        Secure = true // 生产环境必须开启,开发环境可根据情况调整
    };
    
    开发环境若使用HTTP,可改用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 21:15:37