无法正确设置JWT的Exp和Iat

时间:2015-10-24 19:28:07

标签: javascript node.js jwt json-web-token

我对这一点感到有点难过。我正在尝试建立一个有效的JWT。我正在使用node.js和jsonwebtoken中间件。我已经按照repo(located here)上的文档,但我一直得到错误的Exp和Iat。显然我想要做到这一点,以便我不允许已经过期的JWT。

作为测试我有以下代码:

var token = jwt.sign({"id": user._id}, configGeneral.JWT, { expiresIn: '1h' });

var decoded = jwt.decode(token, configGeneral.JWT);

var d1 = new Date(decoded.exp);
var d2 = new Date(decoded.iat);

console.log(decoded);
console.log(d1);
console.log(d2);

这个输出是:

{ id: '56253091fe0397c80133f3e4',
  iat: 1445714161,
  exp: 1445717761 }
Sat Jan 17 1970 19:35:17 GMT+0200 (South Africa Standard Time)
Sat Jan 17 1970 19:35:14 GMT+0200 (South Africa Standard Time)

如何让时间戳不反映javascript时代,而是从现在起1小时后的时间? (对于iat和exp。)

4 个答案:

答案 0 :(得分:14)

此:

new Date().getTime()

以毫秒为单位给你时间。但是jwt令牌(iat,exp)的时间是以秒为单位,因此我们必须将结果除以1000。

var actualTimeInSeconds = new Date().getTime()/1000;

如何在几秒钟内获得一些时间:

(new Date().getTime() + someTimeInSeconds * 1000)/1000

如果您需要1小时后:

(new Date().getTime() + 60 * 60 * 1000)/1000

因为1h = 60min * 60 s

此时您可以在几秒钟内完成jwt令牌和秒计算的时间。您应该只比较这些值。

在您的情况下,您应该将jwt令牌时间与实际时间(以秒为单位)进行比较。如果jwt令牌到期时间大于实际时间,则表示它仍然有效。 来自jwt令牌的文档:

  

exp索赔的处理要求当前日期/时间必须在exp索赔中列出的到期日期/时间之前。

编辑:

要从iat获取coorect日期,请将值乘以1000并添加到新的Date构造函数:

new Date(iat*1000)

答案 1 :(得分:3)

根据Krzysztof Sztompka发布的内容,我可以让Ext显示正确的到期日期。 (我原来的要求是将来1小时)

为了跟踪更改与之前的错误,我不会更新上面的代码,所以这是我更改的内容:

var d = new Date();

var calculatedExpiresIn = (((d.getTime()) + (60 * 60 * 1000)) - (d.getTime() - d.getMilliseconds()) / 1000);

var token = jwt.sign({"id": user._id}, configGeneral.JWT, { expiresIn: calculatedExpiresIn });

console.log现在将显示Ext是我想要的,现在+ 1小时。

要让Iat显示正确的日期(在sign函数中设置它然后在decode函数中进行健全检查),我必须将其设置为有效负载的一部分。我得到了答案here

所以最后让Iat正确显示我将它添加到有效载荷中,如下所示:

var token = jwt.sign({"id": user._id, "iat": (new Date().getTime())}, configGeneral.JWT, { expiresIn: calculatedExpiresIn });

这给出了输出:

{ id: '56253091fe0397c80133f3e4',
  iat: 1445763099706,
  exp: 1445766699705 }
Sun Oct 25 2015 11:51:39 GMT+0200 (South Africa Standard Time)
Sun Oct 25 2015 10:51:39 GMT+0200 (South Africa Standard Time)

这是未编码的JWT,我将在他们成功登录时将其传递给用户,并允许我检查他们必须通过的JWT,因为每个未来的请求仍然有效且尚未过期。< / p>

答案 2 :(得分:0)

该库创建的时代是Unix时代,您可以在任何网站(like this for example)中查看jwt iat和exp值,并且您会发现它们有效

例如,您的问题1445714161中的iat是 格林尼治标准时间:2015年10月24日,星期六,19:16:01

您的exp是1445717761,即格林尼治标准时间:2015年10月24日,星期六,20:16:01

所以这是1小时后的目标,从一开始就是

如果您尝试使用javascript新的Date(1445714161),则会得到错误的时间

因此,根据jsonwebtoken库here的文档,最简单的方法来创建iat(自动创建)和exp声明

您可以通过这种方式轻松设置到期时间

jwt.sign({
  data: 'foobar'
}, 'secret', { expiresIn: 60 * 60 });

甚至更好:

jwt.sign({
  data: 'foobar'
}, 'secret', { expiresIn: '1h' });

这将把exp声明放在jwt中,如下所示,同时为iat和exp设置正确的unix纪元时间(到期时间比在该时间发布晚1小时),例如,它将是这样(可以是在jwt库中轻松验证):

{
  "data": "foobar",
  "iat": 1539549664,
  "exp": 1539553264
}

请注意,上面的expiresIn选项特定于jsonwebtoken库,更通用的方式如下:

jwt.sign({
  exp: Math.floor(Date.now() / 1000) + (60 * 60),
  data: 'foobar'
}, 'secret');

答案 3 :(得分:0)

通过将/usr/sbin/diskutil rename "NO NAME" "TEST2" 添加到*1000exp,您将看到正确的日期。

iat
var d1 = new Date(decoded.exp*1000);