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

如何在.NET Core 5 MVC中存取跨会话JWT Token Cookie实现记住登录功能

现有代码问题修正

你给出的AuthenticationProperties初始化代码存在明显语法错误:ExpiresUtc是DateTimeOffset?类型,不能直接赋值true,这个错误会导致Cookie持久化逻辑失效,你需要修正为匹配刷新令牌有效期的时间值,同时IsPersistent需要动态绑定用户“记住我”的勾选状态:

var authProperties = new AuthenticationProperties
{
    AllowRefresh = true,
    // 与刷新令牌有效期保持一致
    ExpiresUtc = DateTimeOffset.UtcNow.AddMonths(6),
    // 动态绑定前端传入的“记住我”勾选值,未勾选时为会话级Cookie
    IsPersistent = loginModel.RememberMe
};

Login Get接口校验逻辑实现

这套自动刷新登录的逻辑不会默认自动执行,Cookie认证中间件只会验证Cookie本身的签名和有效期,不会自动调用你的外部身份接口刷新JWT,需要你手动在HttpGet类型的Login接口中实现,步骤如下:

  1. 给Login的Get方法添加[AllowAnonymous]特性,避免未登录时被中间件直接拦截跳转
  2. 手动调用HttpContext.AuthenticateAsync读取Cookie中存储的身份信息,哪怕JWT已过期也能拿到你存入的刷新令牌
  3. 调用认证接口执行刷新逻辑,刷新成功后重新写入Cookie直接跳转,失败则清除无效Cookie展示登录页

示例代码如下:

[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> Login(string returnUrl = null)
{
    // 已登录用户直接跳转
    if (User.Identity.IsAuthenticated)
    {
        return Redirect(string.IsNullOrEmpty(returnUrl) ? Url.Action("Index", "Home") : returnUrl);
    }
    // 手动读取Cookie中的身份信息
    var authResult = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);
    if (authResult.Succeeded)
    {
        // 提取之前存入Claims的访问令牌和刷新令牌
        var accessToken = authResult.Principal.FindFirstValue("AccessToken");
        var refreshToken = authResult.Principal.FindFirstValue("RefreshToken");
        // 调用你自己的身份验证API执行刷新
        var refreshResp = await _yourAuthApi.RefreshToken(accessToken, refreshToken);
        if (refreshResp.IsSuccess)
        {
            // 刷新成功,重新构建身份写入Cookie
            var claims = new List<Claim>
            {
                new Claim("AccessToken", refreshResp.NewAccessToken),
                new Claim("RefreshToken", refreshResp.NewRefreshToken)
                // 其他你需要的用户声明
            };
            var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
            var newAuthProps = new AuthenticationProperties
            {
                AllowRefresh = true,
                ExpiresUtc = DateTimeOffset.UtcNow.AddMonths(6),
                // 复用原有持久化配置,保持记住我状态
                IsPersistent = authResult.Properties.IsPersistent
            };
            await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), newAuthProps);
            // 直接跳转目标地址,跳过登录流程
            return Redirect(string.IsNullOrEmpty(returnUrl) ? Url.Action("Index", "Home") : returnUrl);
        }
        // 刷新失败,清除无效Cookie
        await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
    }
    ViewData["ReturnUrl"] = returnUrl;
    return View();
}

额外注意事项

  • 刷新令牌必须做单次有效限制,每次刷新成功后立即废弃旧刷新令牌,下发新的刷新令牌,避免令牌被盗用后被长期滥用
  • 你可以选择将刷新令牌单独存储在独立的HttpOnly加密Cookie中,不要存入Claims,进一步降低令牌泄露风险
  • 确保Cookie配置开启了HttpOnly、Secure(生产环境)属性,避免前端JS读取到Cookie内容

内容的提问来源于stack exchange,提问作者arc-menace

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 13:15:03