use*_*520 5 mongoose mongodb node.js express
我有一个使用一些属性创建的用户模型,这些属性稍后在用户激活后被删除。我注意到这些属性在用户发起忘记密码请求后重新出现。
当我单步执行代码(它是一个快速应用程序)时,我在忘记密码控制器中有一个 User.findOne 请求,该请求返回仍然具有已删除属性的用户文档,因此当我保存密码重置令牌。
function forgotPassword(req, res, next) {
const username = req.body.username;
// Generate token
const token = uuid.v4();
// Find the user
User.findOne({ username: username }, function(err, user) {
if (err) {
return next(err);
}
// At this stage user also has the properties that
// were previously deleted when I inspect it
user.resetToken = token;
user.save(function(err, savedUser, numAffected) {
// So resetToken gets saved but also the previously deleted properties
...
});
Run Code Online (Sandbox Code Playgroud)
我在数据库中验证了它们在用户激活时被删除,然后在忘记密码请求后重新出现。
Mongoose 对 findOne 请求是否有某种缓存?
我浏览了 Mongoose github issues 并没有发现任何东西。Mongoose findOne在幕后使用mquery ,但我看不到缓存层。
如何让 Mongoose 使用数据库中的实时数据?
更新了最小的例子:
[更新:我没有在最小示例中添加任何快速路线,但事件顺序本质上是相同的,尽管在实际应用程序中数据库调用分布在几个不同的快速路线上]
包.json:
{
"name": "minimal-mongoose-findone-old-data-issue",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"chance": "^1.0.11",
"mongoose": "^4.12.4",
"uuid": "^3.1.0"
}
}
Run Code Online (Sandbox Code Playgroud)
索引.js:
const mongoose = require('mongoose');
const uuid = require('uuid');
const chance = new(require('chance'));
const dbPort = process.env.DBPORT;
const dbName = 'minimal-mongoose-findone-old-data-issue';
const mongoUrl = `mongodb://localhost:${dbPort}/${dbName}`;
mongoose.connect(mongoUrl, { user: '', pass: '' });
mongoose.set("debug",true);
const UserSchema = new mongoose.Schema({
username: {
type: String,
unique: true
},
activationToken: {
type: String,
default: uuid.v4()
},
active: {
type: Boolean,
default: false
},
passwordToken: {
type: String
}
}, { timestamps: true });
const User = mongoose.model('User', UserSchema);
// Create user
const username = chance.first();
const user = new User();
user.username = username;
user.save(function(err, savedUser) {
if (err) { throw err };
console.log(`STEP 1: user created: ${JSON.stringify(savedUser, 0, 2)}`);
// Activate user
User.findOne({
activationToken: savedUser.activationToken
}, function(err, foundUser) {
if (err) { throw err };
console.log(`STEP 2: user found: ${JSON.stringify(foundUser, 0, 2)}`);
foundUser.active = true;
foundUser.activationToken = undefined;
foundUser.save(function(err, activatedUser, numAffected) {
if (err) { throw err };
console.log(`STEP 3: user activated: ${JSON.stringify(activatedUser, 0, 2)}`);
// Reset password
User.findOne({
username: username,
}, function(err, resetPasswordUser) {
if (err) { throw err };
console.log(`STEP 4: user found for password reset: ${JSON.stringify(resetPasswordUser, 0, 2)}`);
// Password reset logic here etc...
// The problem is that since the second findOne call returns old data,
// the activationToken gets saved back to the database when I save resetPasswordUser
process.exit();
});
});
});
});
Run Code Online (Sandbox Code Playgroud)
在第3步中,console.log输出没有activationToken
在步骤 4 中,activationToken 又回到了 console.log 输出中
运行节点 index.js 的输出:[使用 mongo 调试输出更新]
Mongoose: users.insert({ updatedAt: new Date("Wed, 25 Oct 2017 08:02:48 GMT"), createdAt: new Date("Wed, 25 Oct 2017 08:02:48 GMT"), username: 'Hannah', _id: ObjectId("59f045287a2de871d0fbce14"), active: false, activationToken: 'c9048f36-02c7-4a0f-8e2c-abf5cb9120fe', __v: 0 })
STEP 1: user created: {
"__v": 0,
"updatedAt": "2017-10-25T08:02:48.107Z",
"createdAt": "2017-10-25T08:02:48.107Z",
"username": "Hannah",
"_id": "59f045287a2de871d0fbce14",
"active": false,
"activationToken": "c9048f36-02c7-4a0f-8e2c-abf5cb9120fe"
}
Mongoose: users.findOne({ activationToken: 'c9048f36-02c7-4a0f-8e2c-abf5cb9120fe' }, { fields: {} })
STEP 2: user found: {
"_id": "59f045287a2de871d0fbce14",
"updatedAt": "2017-10-25T08:02:48.107Z",
"createdAt": "2017-10-25T08:02:48.107Z",
"username": "Hannah",
"__v": 0,
"active": false,
"activationToken": "c9048f36-02c7-4a0f-8e2c-abf5cb9120fe"
}
Mongoose: users.update({ _id: ObjectId("59f045287a2de871d0fbce14") }, { '$unset': { activationToken: 1 }, '$set': { active: true, updatedAt: new Date("Wed, 25 Oct 2017 08:02:48 GMT") } })
STEP 3: user activated: {
"_id": "59f045287a2de871d0fbce14",
"updatedAt": "2017-10-25T08:02:48.153Z",
"createdAt": "2017-10-25T08:02:48.107Z",
"username": "Hannah",
"__v": 0,
"active": true
}
Mongoose: users.findOne({ username: 'Hannah' }, { fields: {} })
STEP 4: user found for password reset: {
"_id": "59f045287a2de871d0fbce14",
"updatedAt": "2017-10-25T08:02:48.153Z",
"createdAt": "2017-10-25T08:02:48.107Z",
"username": "Hannah",
"__v": 0,
"active": true,
"activationToken": "c9048f36-02c7-4a0f-8e2c-abf5cb9120fe"
}
Run Code Online (Sandbox Code Playgroud)
运行index.js后在mongo shell中:
MongoDB shell version: 3.2.4
connecting to: test
> use minimal-mongoose-findone-old-data-issue
switched to db minimal-mongoose-findone-old-data-issue
> db.users.find({ username: 'Hannah'}).pretty()
{
"_id" : ObjectId("59f045287a2de871d0fbce14"),
"updatedAt" : ISODate("2017-10-25T08:02:48.153Z"),
"createdAt" : ISODate("2017-10-25T08:02:48.107Z"),
"username" : "Hannah",
"active" : true,
"__v" : 0
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1457 次 |
| 最近记录: |