JSON Web Token 是一个相当新的标准(2015 年 5 月),但他们决定采用 UNIX 时间戳,以便表示日期。
这是否会使标准在各种实施中面临潜在的“2038 年问题”?相反,选择像 ISO8601 这样的东西似乎更适合未来。 为什么要选择一个而不是另一个?
某些实现(例如 JavaScript)将所有 JSON 数字视为双精度浮点数。虽然它们在宇宙热寂之后才会溢出,但在不到 3 亿年的时间里它们将开始变得不准确,而且随着时间的推移,问题会变得更糟(比如你创建了一个代币,一小时后过期,但该值不能表示为双精度浮点数,最接近的值是 2 小时内,因此直到 2 小时后才会过期)。
其他实现可能使用 64 位有符号整数。这些将在 3000 亿年后溢出,也就是太阳变成红巨星并吞噬地球之后。
唯一容易受到 Y2038 问题影响的实现是在解析日期时决定使用 32 位有符号整数的实现。这样的实施将是愚蠢的。无论你选择什么格式,你都无法避免愚蠢的行为 - ISO8601 在这里没有任何帮助,因为虽然这可能是在线上出现的内容,但每个单独的实现都会将其解析为一定数量的时间自某个纪元以来的单位,因为这是所有计算机处理日期的方式,并且是实际进行计算(例如令牌是否已过期)的唯一方法。因此,每个实现,即使使用 ISO8601,也很容易选择精度太低的数字表示形式来处理特定时间之后的日期,包括选择带符号的 32 位整数来表示自 1970 年以来的秒数,就像 Y2038 问题一样。每个实现都需要选择适当大小的数字类型来表示其解析的日期,您可能会发现它们都这样做(如果没有,您应该报告错误)。
所以,不,JWT 使用自 UNIX 纪元以来的秒数来表示日期没有任何问题。
在大多数情况下,JWT 中的日期声明应该与
NOW()
进行比较(想想
exp
声明),因此在那里使用时间戳是有意义的。我不会担心 Y2038 错误,因为 32 位系统会比发行 JWT 遇到更大的问题。