如何检查从req.user的用户ID从Passport JS和MongdoDB用户ID匹配更新/删除文档之前?
我正在为使用Passport JS
+进行身份validation的用户创build一个具有delete and edit
function的投票应用程序,具体的投票属于他/她。
我有以下的Passport setup
与Node/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 poll
function。
问题是,它检查用户是否通过身份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
否则就不会有任何更新。
希望这会有所帮助。
使用deleteOne
或updateOne
的filter
参数进行deleteOne
:
db.collection(POLLS_COLLECTION).deleteOne({ _id: new ObjectID(req.params.id), userID: req.user._id, }, function(err, doc) { … }); });
您也可以首先获取您的投票对象,然后在该查询中使用.then
,只有在条件匹配的情况下才能删除,但是在这种情况下,您可以自己解决并发问题而无需写入locking。 (有人可以在检查投票是否属于该用户时更改投票对象的用户标识 – 那么你会怎么做?)