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

如何设置JWT Token长期有效期?100年期限提示无过期时间报错

问题分析与解决

问题重现

用户生成JWT的代码如下:

private string GenerateJSONWebToken(pswd user)
{
    var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
    var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
    var token = new JwtSecurityToken(_config["Jwt:Issuer"],
        _config["Jwt:Issuer"],
        null,
        expires: DateTime.Now.AddYears(100),
        signingCredentials: credentials);
        
    return new JwtSecurityTokenHandler().WriteToken(token);
}

设置100年过期时间后,出现“no expiry”错误,Token无法访问目标Web API;但设置10年以内过期时间时,Token可正常工作并返回200状态码。

原因解析

JWT的exp(过期时间)声明采用Unix时间戳(从1970-01-01T00:00:00Z到目标时间的秒数),而32位Unix时间戳的最大值对应2038-01-19T03:14:07Z。当设置DateTime.Now.AddYears(100)时,该时间大概率会超过2038年,导致生成的Unix时间戳溢出,在JWT解析时会被判定为无效,甚至被误认为未设置exp声明,从而触发“no expiry”错误。此外,部分JWT验证库会对极端遥远的过期时间做特殊校验,直接判定为无效,也会引发该问题。

解决方案

1. 接近永久的合规有效期

若需要接近永久的有效期,建议将过期时间设置为2038年1月19日之前,避免32位时间戳溢出问题:

// 设置为2038年1月1日UTC时间,避开时间戳溢出临界点
var expires = new DateTime(2038, 1, 1, 0, 0, 0, DateTimeKind.Utc);
var token = new JwtSecurityToken(_config["Jwt:Issuer"],
    _config["Jwt:Issuer"],
    null,
    expires: expires,
    signingCredentials: credentials);

2. 不设置exp声明(不推荐)

若完全不需要过期时间,可以省略expires参数,生成不带exp声明的JWT。但这种方式会让Token永久有效,一旦泄露无法失效,存在严重安全隐患,仅适用于非敏感场景:

var token = new JwtSecurityToken(_config["Jwt:Issuer"],
    _config["Jwt:Issuer"],
    null,
    signingCredentials: credentials);

3. 自定义永久有效逻辑(灵活可控)

可以添加自定义声明标记永久有效,再在API的JWT验证逻辑中跳过过期时间校验,兼顾安全性与需求:

生成Token时添加自定义声明

var claims = new[]
{
    new Claim("permanent", "true")
};
var token = new JwtSecurityToken(_config["Jwt:Issuer"],
    _config["Jwt:Issuer"],
    claims,
    signingCredentials: credentials);

验证时处理自定义声明(以ASP.NET Core为例)

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = _config["Jwt:Issuer"],
            ValidAudience = _config["Jwt:Issuer"],
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"])),
            // 自定义生命周期校验逻辑
            LifetimeValidator = (before, expires, token, parameters) =>
            {
                var permanentClaim = token.Claims.FirstOrDefault(c => c.Type == "permanent" && c.Value == "true");
                if (permanentClaim != null)
                {
                    return true;
                }
                // 无永久声明时按正常过期时间校验
                return expires != null && expires > DateTime.UtcNow;
            }
        };
    });

内容的提问来源于stack exchange,提问作者Yuvraj Jadhav

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 11:42:58