无法将 jwt.iat(发布于)属性与当前日期时间进行比较 - (“自纪元以来的秒数”NumericDate)

ope*_*sas 1 javascript datetime datetimeoffset gmt jwt

我从 Web 服务获取 json Web 令牌,解码后返回如下内容:

\n
{\n  "exp": 1572468916,\n  "iat": 1572468316,\n  "iss": "https://ccc/auth/realms/yyy",\n  "aud": "xxx-api",\n  [...]\n
Run Code Online (Sandbox Code Playgroud)\n

根据第 2 节终端学, NumericDate 数据类型对应于“自纪元以来的秒数”

\n

所以我将它转换为 JavaScript 日期,如下所示:

\n
new Date(1572468316 * 1000)\nDate Wed Oct 30 2019 17:45:16 GMT-0300 (Argentina Standard Time)\n
Run Code Online (Sandbox Code Playgroud)\n

问题是我当前的时间是:

\n
new Date()\nDate Wed Oct 30 2019 14:45:19 GMT-0300 (Argentina Standard Time)\n
Run Code Online (Sandbox Code Playgroud)\n

实际上,当前时间是返回的时间new Date()(即 14:45,不是 17:45)

\n

我猜这与 GMT 有关,但我不知道如何处理它。

\n

我想将 iat 属性(显然还有 exp 属性)转换为当前时间,以便将其进行比较以new Date()查明令牌是否已过期。

\n

那么如何将 NumericDate 从 json Web 令牌 iat/exp 属性转换为本地时间以进行比较?

\n

Mat*_*int 5

和值确实以自 Unix 纪元以来iatexp秒数表示。由于 Unix 纪元是基于 UTC 的,因此这些值也是基于 UTC 的。您正在Date正确地将它们转换为对象。

var iat = new Date(1572468316 * 1000);
var exp = new Date(1572468916 * 1000);

console.log(iat.toISOString()); //=> "2019-10-30T20:45:16.000Z"
console.log(exp.toISOString()); //=> "2019-10-30T20:55:16.000Z"
Run Code Online (Sandbox Code Playgroud)

toISOString函数发出 ISO 8601 格式的字符串,以 UTC 形式表示(如尾随Z字符所示)。

您在问题中给出的输出格式是调用函数时toString或在Date选择记录输出的环境中直接记录对象时会发生的情况toString。由于不同的环境可以发出不同的格式(有些是本地时间,有些是 UTC,有些是 ISO 8601,有些是非标准格式) - 不建议直接记录对象Date

输出toISOString显示 JWT 的有效期为 10 分钟,从 2019-10-30 20:45:16 UTC 到 2019-10-30 20:55:16 UTC。没有其他方法可以解释这些结果。

您的本地时间输出显示三小时转换,这将正确对应于 UTC-3 时区偏移,再次确认它们的值正在被正确解析。

如果这不是您所期望的,则令牌未正确颁发。正在发生以下两件事之一:

  • 生成 JWT 的代码中可能存在错误,因为它使用本地时间而不是 UTC 作为创建时间戳的基础。

  • 运行生成 JWT 的代码的服务器的时钟设置可能不正确。

第二种说法更为合理。例如,当服务器管理员将时区设置为 UTC 但根据本地时间设置时钟时,可能会发生这种情况。相反,确保服务器上的时钟设置为自动从互联网同步时间,问题可能就会消失。

关于问题评论中提到的方法 -不要这样做。以这种方式减去时区偏移量并不能正确调整时区,而是选择不同的时间点。它可能看起来提供了正确的结果,但您会发现许多时区中夏令时转换的边缘情况,并且一旦开始使用正确的值生成 JWT,您就会遇到问题。