.NET Core 3.1 JWT刷新提示令牌过期,生成时间异常问题排查
问题原因与解决方案
核心问题是JWT令牌生成时使用了本地时间DateTime.Now,而非UTC时间DateTime.UtcNow。JWT标准要求令牌的过期时间(exp)和签发时间(iat)必须基于UTC时间,使用本地时间会导致时间转换错误,出现ValidTo早于实际当前时间的情况,最终触发过期验证失败。
具体修改步骤:
修正令牌生成逻辑
在GenerateToken方法中,将DateTime.Now替换为DateTime.UtcNow,同时显式设置IssuedAt字段确保签发时间也为UTC:public string GenerateToken(AppUser user) { var tokenHandler = new JwtSecurityTokenHandler(); var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwt.SecurityKey)); var tokenDesciptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity( new Claim[] { new Claim(ClaimTypes.Name,user.username), new Claim(ClaimTypes.Role,user.userType), new Claim("userCode",user.userCode), new Claim("userTypeCode",user.userTypeCode), new Claim("Mobile",user.Mobile??""), new Claim("email",user.email??""), new Claim("gender",user.genderCode??""), new Claim("username",user.username), new Claim("fname",user.name) } ), // 使用UTC时间设置过期时间 Expires = DateTime.UtcNow.AddMinutes(_jwt.DurationInMinutes), // 显式设置签发时间为UTC,确保时间一致性 IssuedAt = DateTime.UtcNow, SigningCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256), Audience=_jwt.Audience, Issuer=_jwt.Issuer }; var tokenStr = tokenHandler.CreateToken(tokenDesciptor); string token = tokenHandler.WriteToken(tokenStr); return token; }确保刷新逻辑中的时间判断统一使用UTC
在Refresh方法中,当前的jwtToken.ValidTo > DateTime.UtcNow判断是正确的,无需修改,但要保证生成的令牌ValidTo是UTC时间,这个修改已经在第一步完成。验证服务器时区一致性
确保API服务器的系统时区设置与业务预期一致,避免因时区差异导致的时间解析错误。
原理说明:
当你使用DateTime.Now设置Expires时,JWT处理程序会自动将本地时间转换为UTC存储到令牌的exp字段中。假设你的服务器时区为UTC+5,本地下午3点生成的令牌,转换为UTC后是上午10点,此时ValidTo会被设置为上午10点。当你在本地下午3点调用刷新接口时,UTC时间是上午10点,验证逻辑会认为令牌已经过期,从而抛出IDX10223错误。使用DateTime.UtcNow可以确保令牌的时间字段与验证逻辑使用的时间基准完全一致。
内容的提问来源于stack exchange,提问作者nitin mandal
相关产品推荐
相关产品推荐

