如何检查从req.user的用户ID从Passport JS和MongdoDB用户ID匹配更新/删除文档之前?

我正在为使用Passport JS +进行身份validation的用户创build一个具有delete and editfunction的投票应用程序,具体的投票属于他/她。

我有以下的Passport setupNode/Express

  passport.use(new FacebookStrategy({ clientID: FACEBOOK_APP_ID, clientSecret: FACEBOOK_APP_SECRET, callbackURL: CALLBACK_URL }, function(accessToken, refreshToken, profile, done){ //callback function after login process.nextTick(function(){ done(null, profile); }); })); passport.serializeUser(function(user,done){ req.session.passport.user = {}; done(null, user); }); passport.deserializeUser(function(id, done){ done(null, id); }); app.get('/auth/facebook', passport.authenticate('facebook')); app.get('/auth/facebook/callback', passport.authenticate('facebook', { successRedirect: '/', failureRedirect: '/error' })); app.get('/success', function(req, res, next) { res.send('Successfully logged in. You can close this window'); }); app.get('/error', function(req, res, next) { res.send("Error logging in."); }); 

所以,现在每个请求都有用户使用id和displayName连接到它(req.user)

我使用以下中间件function来保护路由服务器端:

 var auth = function(req,res,next){ if(!req.isAuthenticated()){ console.log("You need to login!"); res.sendStatus(401); } else { console.log("User is logged in, success!"); next(); } }; 

民意调查在MongoDB中以下列格式保存:

 { "_id": { "$oid": "57c69ec65ed24f166b4e98cf" }, "title": "Poll Test", "options": [ { "option": "Option1", "votes": 0 }, { "option": "Option2", "votes": 0 }, { "option": "Option3", "votes": 0 }, { "option": "Option4", "votes": 0 } ], "userID": "1798846357", "displayName": "John Doe", "date": "Wed Aug 31 2016 09:09:26 GMT+0000 (UTC)" } 

我想从我的REST API中保护以下路由,例如前端的delete pollfunction。

问题是,它检查用户是否通过身份validation,但是如果该用户属于该用户,则不会。 换句话说:如果请求中的userID和数据库中的userID匹配,则不是。

我尝试在db.collection函数中添加一个if语句来检查req.user.id and doc.data.id match但是它不起作用。

我认为这是因为updateOne已经完成了。

我怎样才能检索用userID的民意调查,然后用req.user.id检查,如果匹配,继续更新?

  app.delete("/polls/:id", auth, function(req, res) { db.collection(POLLS_COLLECTION).deleteOne({ _id: new ObjectID(req.params.id) }, function(err, doc) { if (err) { handleError(res, err.message, "Failed to delete contact"); } else { res.status(204).end(); } }); }); }); 

这可以帮助你:

回答这个问题

How can I retrieve the poll with the userID and then check that with the req.user.id and if match, continue with the update?

 db.collectionName.updateOne({userID : req.user.id}, {updateQuery}); 

上面的查询将更新文档,如果有任何文档与userID相同的值req.user.id 否则就不会有任何更新。

希望这会有所帮助。

使用deleteOneupdateOnefilter参数进行deleteOne

 db.collection(POLLS_COLLECTION).deleteOne({ _id: new ObjectID(req.params.id), userID: req.user._id, }, function(err, doc) { … }); }); 

您也可以首先获取您的投票对象,然后在该查询中使用.then ,只有在条件匹配的情况下才能删除,但是在这种情况下,您可以自己解决并发问题而无需写入locking。 (有人可以在检查投票是否属于该用户时更改投票对象的用户标识 – 那么你会怎么做?)