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

ASP.NET Core会话1小时过期,如何延长或使用刷新令牌?

解决ASP.NET Core中Firebase认证会话持久化问题

一、使用Firebase刷新令牌自动续期ID Token

Firebase的ID Token默认1小时过期,仅延长ASP.NET Core会话时长无法解决令牌本身失效的问题,必须利用**刷新令牌(Refresh Token)**自动获取新的ID Token,维持用户登录状态。

1. 登录时存储必要信息

修改登录代码,除ID Token外,额外保存刷新令牌和令牌过期时间:

try
{
    var fbAuthLink = await auth.SignInWithEmailAndPasswordAsync(account.Email, account.Password);
    string idToken = fbAuthLink.FirebaseToken;
    string refreshToken = fbAuthLink.RefreshToken;
    // 计算令牌过期时间(当前UTC时间 + 有效期秒数)
    var expiresAt = DateTime.UtcNow.AddSeconds(fbAuthLink.ExpiresIn);

    if (!string.IsNullOrEmpty(idToken))
    {
        // 存储到会话
        HttpContext.Session.SetString("_UserToken", idToken);
        HttpContext.Session.SetString("_RefreshToken", refreshToken);
        HttpContext.Session.SetString("_TokenExpiresAt", expiresAt.ToString("o")); // 用ISO格式存储时间

        var a = _accountRepo.GetAccountByUID(fbAuthLink.User.LocalId);
        if (!a.IsSubscribed)
        {
            return RedirectToAction("Checkout", "Stripe");
        }
        return RedirectToAction("Index");
    }
    else
    {
        return View();
    }
}
catch (Exception ex)
{
    ModelState.AddModelError("", "登录失败:" + ex.Message);
    return View();
}

2. 实现自动续期逻辑

创建令牌检查与续期方法,通过中间件或动作过滤器在每次请求前执行:

public async Task RefreshTokenIfNeeded(HttpContext context, FirebaseAuthProvider authProvider)
{
    var idToken = context.Session.GetString("_UserToken");
    var refreshToken = context.Session.GetString("_RefreshToken");
    var expiresAtStr = context.Session.GetString("_TokenExpiresAt");

    // 验证存储信息有效性
    if (string.IsNullOrEmpty(idToken) || string.IsNullOrEmpty(refreshToken) || 
        !DateTime.TryParse(expiresAtStr, out var expiresAt))
    {
        // 无有效令牌,跳转登录页
        context.Response.Redirect("/Account/Login");
        return;
    }

    // 提前5分钟检查续期(避免令牌刚过期时请求失败)
    if (DateTime.UtcNow.AddMinutes(5) >= expiresAt)
    {
        try
        {
            // 用刷新令牌获取新认证信息
            var refreshedAuthLink = await authProvider.RefreshAuthAsync(refreshToken);
            
            // 更新会话中的令牌和过期时间
            context.Session.SetString("_UserToken", refreshedAuthLink.FirebaseToken);
            context.Session.SetString("_RefreshToken", refreshedAuthLink.RefreshToken);
            var newExpiresAt = DateTime.UtcNow.AddSeconds(refreshedAuthLink.ExpiresIn);
            context.Session.SetString("_TokenExpiresAt", newExpiresAt.ToString("o"));
        }
        catch (Exception)
        {
            // 刷新令牌失效(如用户密码更改),跳转登录页
            context.Response.Redirect("/Account/Login");
            return;
        }
    }
}

如果用中间件,在Program.cs中注册(需放在UseSession之后、UseRouting之前):

app.UseSession();

app.Use(async (context, next) =>
{
    var authProvider = new FirebaseAuthProvider(new FirebaseConfig("你的Firebase API Key"));
    await RefreshTokenIfNeeded(context, authProvider);
    await next();
});

app.UseRouting();
// 其他中间件...

二、延长ASP.NET Core会话时长

若需延长会话本身的闲置超时,在Program.cs中配置会话:

builder.Services.AddSession(options =>
{
    options.IdleTimeout = TimeSpan.FromHours(8); // 设置闲置8小时后过期
    options.Cookie.HttpOnly = true; // 禁止前端JS访问,提升安全性
    options.Cookie.IsEssential = true; // 标记为必要Cookie,符合合规要求
    options.Cookie.SecurePolicy = CookieSecurePolicy.Always; // 生产环境启用,仅HTTPS传输
});

注意:必须确保app.UseSession()在app.UseRouting()和app.UseAuthorization()之前调用,否则会话无法正常工作。

三、进阶:用Cookie持久化刷新令牌

如果需要“记住我”这类长期登录功能,可将刷新令牌存储在HttpOnly Cookie中(而非会话):

// 登录时设置Cookie
var cookieOptions = new CookieOptions
{
    HttpOnly = true,
    Secure = true,
    Expires = DateTime.UtcNow.AddDays(7), // 7天过期
    SameSite = SameSiteMode.Strict
};
context.Response.Cookies.Append("FirebaseRefreshToken", refreshToken, cookieOptions);
context.Response.Cookies.Append("FirebaseTokenExpiresAt", expiresAt.ToString("o"), cookieOptions);

续期时从Cookie读取刷新令牌,替换会话的读取逻辑即可。


内容的提问来源于stack exchange,提问作者Reed Kammerman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 13:20:05