【发布时间】:2019-02-02 10:33:08
【问题描述】:
我的 db.user mongoDB 集合中有两个字段:“password_hash”和“password_token”。我可以从 API 更新“password_hash”(通过快速路由卷曲到猫鼬模型),但我无法使用几乎完全相同的代码更新“password_token”。我可以从 Studio3t 中“手动”修改任何一个,但这会破坏编写 API 的目的。我还认为这意味着这种行为与数据库集合上的索引、验证器等无关,因为我可以在任一字段中保存值。当我尝试从 API 执行相同操作时,我没有收到错误消息,只有 { ok: 0, n: 0, nModified: 0 } 并且没有更新的字段。
以下是缩写文档:
"username" : "user1",
"password_hash" : "$2a$10$pVTT8FS.WV.sba1wvVwYMu7hMqaGkP1toJx5PGMXrl/ZnLyLtqsYy",
"password_token" : ""
这是我正在使用的 curl 命令:
# curl -w '\n' -H "Content-Type: application/json" -X POST -d '{ "username": "user1"}' http://localhost:3000/users/save_hash
{"success":true,"message":"Saved a hash for user1."}
# curl -w '\n' -H "Content-Type: application/json" -X POST -d '{ "username": "user1"}' http://localhost:3000/users/reset_user
{"success":true,"message":"Saved a reset token for user1."}
...都返回成功,如所写,但第二个对数据库字段“password_token”没有影响。
以下是结构相同的快速路线:
router.post('/save_hash', (req, res, next) => {
const username = req.body.username;
User.getUserByUsername(username, (err, user) => {
if (err) logger.error(err);
if (user) {
bcrypt.hash(user.password, 10, (err, hash) => {
if (hash) {
User.saveHash(user.username, hash, err);
return res.json({success: true, message: 'Saved a hash for ' + user.username + '.'});
}
})
}
})
});
router.post('/reset_user', (req, res, next) => {
const username = req.body.username;
User.getUserByUsername(username, (err, user) => {
if (err) logger.error(err);
if (user) {
crypto.randomBytes(20, (err, buffer) => {
if (buffer) {
const token = buffer.toString('hex');
User.resetToken(user.username, 'test', err);
if (err) {logger.error(err) } else {
return res.json({success: true, message: 'Saved a reset token for ' + user.username + '.'});
}
}
});
}
})
});
以下是模型上结构相同的方法:
module.exports.saveHash = function (username, password_hash, callback) {
const query = {'username': username};
User.update(query, { $set: { 'password_hash': password_hash }}, (err_update, raw) => {
if (err_update) { logger.error(err_update); } else {console.log('raw data: ', raw)}
})
};
module.exports.resetToken = function (username, token, callback) {
const query = {'username': username};
User.update(query, { $set: { 'password_token': token}}, (err_update, raw) => {
if (err_update) { logger.error(err_update); } else {console.log('raw data: ', raw)}
})
};
“password_hash”的卷曲、路由和模型按预期工作。相同的重复更新“password_token”不起作用。甚至以下修改也有效:
module.exports.resetToken ...
User.update(query, { $set: { 'password_hash': token}}... // works. updates "password_hash" to the token value.
module.exports.resetToken ...
User.update(query, { $set: { 'password_hash': 'test'}}... // works. updates "password_hash" to 'test'.
...但是如果我修改 saveHash(),它目前用于更新“password_hash”,因此它应该改为“password_token”,它不会修改“password_token”:
module.exports.saveHash ...
User.update(query, { $set: { 'password_token': 'test'}}... /* Does not work. returns { ok: 0, n: 0, nModified: 0 } ...and does not modify "password_token". */
...因此,password_token 字段本身似乎存在“问题”,因为我可以使用完全相同的代码更新不同的字段。
对于它的价值:我读过的所有文档都说我应该能够在尚不存在的字段上调用 update() 并且它将由隐式 $set 创建,但我还没有发现是这样的。在更新之前,我必须使用 MongoShell 创建“password_hash”和“password_token”:
db.users.update({},
{$set : {"password_token":""}},
{upsert:false,
multi:true})
...所以我想知道我是否可能在版本地狱中,我终于看到了症状。
TL:DR;我可以很好地更新一个字段“password_hash”,但另一个字段“password_token”(以及我添加的任何其他字段)无法更新并且不会返回错误,使用基本相同的 curl、route 和模型方法。什么给了?
【问题讨论】:
-
您的
User架构中是否定义了像password_token这样的附加字段? -
是的,用户架构中缺少新字段。每次我添加一个新字段时......每次。
标签: node.js angular mongodb express mongoose