将ObjectID与jwt.sign()和verify()一起使用

时间:2017-08-05 03:43:31

标签: json node.js mongodb mongoose bson

登录我的系统后,我通过jsonwebtoken_id方法运行登录用户的MongoDB sign。它返回给我一个哈希值,然后我将其放入客户端向我的服务器发出的每个后续请求的会话头中。

我现在想解码会话并从头文件中恢复字符串_id,因此我针对jsonwebtoken的verify方法运行它。我没有这样做进行身份验证(已经通过在数据库中查看会话来处理)。我正在恢复_id,因此我可以将用户的活动记录在单独的集合中。我通过中间件运行verify函数并将解码结果保存在req.decoded

但是,当我记录req.decoded时,它是一个BSON对象,而不是一个字符串:

{ _bsontype: 'ObjectID',
  id:
   { type: 'Buffer',
     data: [ 89, 128, 145, 134, 118, 9, 216, 20, 175, 174, 247, 33 ] },
  iat: 1501903389,
  exp: 1501989789 }

如何从此对象中恢复_id值,以便我可以在我的集合中再次查找此记录?

我尝试了什么

我尝试过以下操作,但没有成功:

  • model.find(req.decoded).then()给了我这个错误:

    错误:对象[此处req.decoded的内容]不是有效的ObjectId

  • model.find({_id: req.decoded})给了我这个错误:

    {CastError:对于值[此处为req.decoded的内容],在路径" _id"中转换为ObjectId失败对于模型[这里的模型]

  • req.decoded.toString() logs [object Object]

  • JSON.stringify(req.decoded)只需将BSON变成字符串

1 个答案:

答案 0 :(得分:1)

这当然是主要的,因为你首先实际向.sign()提供数据,而不仅仅是提供ObjectID 的“对象”。通过提供价值来代替。

这实际上涵盖在general usage for .sign()中:

  

如果有效载荷不是缓冲区或字符串,则使用JSON.stringify将其强制转换为字符串。

因此简而言之,该版本将“字符串化”对象形式需要一些“挖掘”。在您的表单中,解码对象的属性为id,子属性为data,其中包含的字节数可以转换为Buffer。这就是你所做的:

  let newId = Buffer.from(req.decoded.id.data).toString('hex');

然后newId将是由字节的'hex'编码值表示的“字符串”。这当然会在任何“查询”或“更新”中发布时被mongoose翻译为ObjectId,以匹配_id的模式。

当然,“替代”只是.sign()首先使用.toString()中的ObjectId值。然后,.verify()的结果只是提供的“十六进制字符串”,而不是JSON.stringify本身的ObjectID结果。

使用列表进行演示:

const bson = require('bson'),
      jwt = require('jsonwebtoken');

// Stored ObjectID
console.log("Round 1");
(function() {
  let id = new bson.ObjectID();
  console.log("Created: %s", id);

  let token = jwt.sign(id,'shhh');                // Supply value as ObjectID
  let decoded = jwt.verify(token,'shhh');

  console.log("Interim");
  console.log(decoded);

  let newId = Buffer.from(decoded.id.data).toString('hex');
  console.log("Decoded: %s", newId);
})();

console.log("\nRound 2");
// Stored String value
(function() {

  let id = new bson.ObjectID();
  console.log("Created: %s", id);

  let token = jwt.sign(id.toString(), 'shhh');    // Supply value as string
  let decoded = jwt.verify(token,'shhh');

  console.log("Decoded: %s", decoded);

})();

给出输出,显示输入值和解码值:

Round 1
Created: 59857328090c497ce787d087
Interim
{ _bsontype: 'ObjectID',
  id:
   { type: 'Buffer',
     data: [ 89, 133, 115, 40, 9, 12, 73, 124, 231, 135, 208, 135 ] },
  iat: 1501917992 }
Decoded: 59857328090c497ce787d087

Round 2
Created: 59857328090c497ce787d088
Decoded: 59857328090c497ce787d088

并演示了为.sign()提供价值的两种形式,以及随后的.verify()来电中提供的内容。