将 ObjectID 与 jwt.sign() 和 verify() 结合使用
Using ObjectID with jwt.sign() and verify()
登录到我的系统后,我通过 jsonwebtoken 的 sign
方法 运行 登录用户的 MongoDB _id
。它 returns 对我来说是一个散列,然后我将其放入客户端向我的服务器发出的每个后续请求的 session headers 中。
我现在想解码 session 并从 headers 恢复字符串 _id
,所以我 运行 它反对 jsonwebtoken 的 verify
方法.我这样做不是为了身份验证(这已经通过在数据库中查找 session 来处理)。我正在恢复 _id
,这样我就可以在单独的 collection 中记录用户的活动。我通过中间件运行 verify
函数并将解码结果保存在req.decoded
.
然而,当我记录 req.decoded
时,它是一个 BSON object,而不是一个字符串:
{ _bsontype: 'ObjectID',
id:
{ type: 'Buffer',
data: [ 89, 128, 145, 134, 118, 9, 216, 20, 175, 174, 247, 33 ] },
iat: 1501903389,
exp: 1501989789 }
如何从 object 中恢复 _id
值,以便我可以在我的 collection 中再次查找此记录?
我试过的
我尝试了以下方法,但没有成功:
model.find(req.decoded).then()
给我这个错误:
错误:object [此处 req.decoded 的内容] 不是有效的 ObjectId
model.find({_id: req.decoded})
给我这个错误:
{ CastError:投射到 ObjectId 在模型 [model here]
的路径“_id”处的值 [req.decoded 的内容] 失败
req.decoded.toString()
日志 [object Object]
JSON.stringify(req.decoded)
只是把BSON变成了字符串
这当然是主观的,首先取决于您实际向 .sign()
提供数据的方式,这是简单地提供 ObjectID
"object" 的区别] 或 通过提供值来代替。
这实际上包含在 general usage for .sign()
中:
If payload is not a buffer or a string, it will be coerced into a string using JSON.stringify.
所以简而言之,该版本将 "stringify" 对象形式需要一些 "digging"。在您的表单中,解码后的对象具有 id
的属性和 data
的子 属性,其中包含一个字节数组,可以转换为 Buffer
。这就是你所做的:
let newId = Buffer.from(req.decoded.id.data).toString('hex');
然后 newId
将是一个 "string",由字节的 'hex'
编码值表示。当在任何 "query" 或 "update" 中发布时,这当然会被 mongoose 翻译成 ObjectId
以匹配 _id
.
的模式
当然,"alternative" 只是 .sign()
首先使用 ObjectId
中的 .toString()
值。那么 .verify()
的结果将只是提供的 "hex string",而不是 ObjectID
本身的 JSON.stringify
结果。
用清单进行演示:
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()
调用的结果。
登录到我的系统后,我通过 jsonwebtoken 的 sign
方法 运行 登录用户的 MongoDB _id
。它 returns 对我来说是一个散列,然后我将其放入客户端向我的服务器发出的每个后续请求的 session headers 中。
我现在想解码 session 并从 headers 恢复字符串 _id
,所以我 运行 它反对 jsonwebtoken 的 verify
方法.我这样做不是为了身份验证(这已经通过在数据库中查找 session 来处理)。我正在恢复 _id
,这样我就可以在单独的 collection 中记录用户的活动。我通过中间件运行 verify
函数并将解码结果保存在req.decoded
.
然而,当我记录 req.decoded
时,它是一个 BSON object,而不是一个字符串:
{ _bsontype: 'ObjectID',
id:
{ type: 'Buffer',
data: [ 89, 128, 145, 134, 118, 9, 216, 20, 175, 174, 247, 33 ] },
iat: 1501903389,
exp: 1501989789 }
如何从 object 中恢复 _id
值,以便我可以在我的 collection 中再次查找此记录?
我试过的
我尝试了以下方法,但没有成功:
model.find(req.decoded).then()
给我这个错误:错误:object [此处 req.decoded 的内容] 不是有效的 ObjectId
model.find({_id: req.decoded})
给我这个错误:{ CastError:投射到 ObjectId 在模型 [model here]
的路径“_id”处的值 [req.decoded 的内容] 失败
req.decoded.toString()
日志 [object Object]JSON.stringify(req.decoded)
只是把BSON变成了字符串
这当然是主观的,首先取决于您实际向 .sign()
提供数据的方式,这是简单地提供 ObjectID
"object" 的区别] 或 通过提供值来代替。
这实际上包含在 general usage for .sign()
中:
If payload is not a buffer or a string, it will be coerced into a string using JSON.stringify.
所以简而言之,该版本将 "stringify" 对象形式需要一些 "digging"。在您的表单中,解码后的对象具有 id
的属性和 data
的子 属性,其中包含一个字节数组,可以转换为 Buffer
。这就是你所做的:
let newId = Buffer.from(req.decoded.id.data).toString('hex');
然后 newId
将是一个 "string",由字节的 'hex'
编码值表示。当在任何 "query" 或 "update" 中发布时,这当然会被 mongoose 翻译成 ObjectId
以匹配 _id
.
当然,"alternative" 只是 .sign()
首先使用 ObjectId
中的 .toString()
值。那么 .verify()
的结果将只是提供的 "hex string",而不是 ObjectID
本身的 JSON.stringify
结果。
用清单进行演示:
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()
调用的结果。