在Mongodb中创建Express route后,如何修改它以登录用户?
我有下面的路线。如果我在MongoDB中手动添加文档,它就会工作。但是,我想处理这样一种情况:找不到用户,创建用户,然后自动登录 修改此路线的最佳方式是什么在Mongodb中创建Express route后,如何修改它以登录用户?,mongodb,express,Mongodb,Express,我有下面的路线。如果我在MongoDB中手动添加文档,它就会工作。但是,我想处理这样一种情况:找不到用户,创建用户,然后自动登录 修改此路线的最佳方式是什么 router.post("/loginViaFacebook", (req, res) => { const userEmail = req.body.email; const errors = {}; User.findOne({ email: userEmail }).then(user => { if
router.post("/loginViaFacebook", (req, res) => {
const userEmail = req.body.email;
const errors = {};
User.findOne({ email: userEmail }).then(user => {
if (!user) {
new User({
facebookId: req.body.facebookId,
name: req.body.name,
email: req.body.email,
pictureUrl: req.body.picture
}).save();
} else {
const payload = {
facebookId: user.id,
name: user.name,
email: user.email,
pictureUrl: user.picture
};
jwt.sign(payload, secretOrKey, { expiresIn: 3600 }, (err, token) => {
res.json({ success: true, token: "Bearer " + token });
});
console.log("success!");
}
});
});
将新用户对象保存到数据库后,可以从返回的结果中获取id。我不太了解mongo,因此您必须查看从
.save()
返回的结果,然后从中提取id。以下是总体结构:
const promisify = require('util').promisify;
const jwt.signPromise = promisify(jwt.sign);
/**
* @route POST api/auth/loginViaFacebook
* @desc Login User via Facebook/
* @access public
*/
router.post("/loginViaFacebook", async (req, res) => {
const userEmail = req.body.email;
const errors = {};
try {
let user = await User.findOne({
email: userEmail
});
if (!user) {
user = new User({
facebookId: req.body.facebookId,
name: req.body.name,
email: req.body.email,
pictureUrl: req.body.picture
});
user = await user.save();
}
const payload = {
facebookId: user.facebookId,
name: user.name,
email: user.email,
pictureUrl: user.picture
};
let token = await jwt.signPromise(payload, secretOrKey, {expiresIn: 3600});
res.json({success: true, token: "Bearer " + token});
} catch (e) {
// send some sort of error response here
console.log(e);
res.sendStatus(500);
}
});
如果您不想使用wait
,而想保持原来的结构,只需将复制的代码移动到一个公共函数中即可
/**
* @route POST api/auth/loginViaFacebook
* @desc Login User via Facebook/
* @access public
*/
router.post("/loginViaFacebook", (req, res) => {
const userEmail = req.body.email;
const facebookId = req.body.facebookId;
function finish(user) {
const payload = {
facebookId: user.facebookId,
name: user.name,
email: user.email,
pictureUrl: user.picture
};
jwt.sign(payload, secretOrKey, { expiresIn: 3600 }, (err, token) => {
if (err) {
console.log(err);
res.sendStatus(500);
return;
}
res.json({ success: true, token: "Bearer " + token });
});
return;
}
// Find user by email. ( Down below { email } in ES6 is same as { email: email }
User.findOne({ email: userEmail }).then(user => {
if (!user) {
new User({
facebookId: facebookId,
name: req.body.name,
email: userEmail,
pictureUrl: req.body.picture
}).save(function(err, user) {
if (err) {
res.send({ errors: err });
return;
}
finish(user);
});
} else {
finish(user);
}
}).catch(err => {
console.log(err);
res.sendStatus(500);
});
});
我最终修改了代码,如下所示:
/**
* @route POST api/auth/loginViaFacebook
* @desc Login User via Facebook/
* @access public
*/
router.post("/loginViaFacebook", (req, res) => {
const userEmail = req.body.email;
const facebookId = req.body.facebookId;
// Find user by email. ( Down below { email } in ES6 is same as { email: email }
User.findOne({ email: userEmail }).then(user => {
if (!user) {
new User({
facebookId: facebookId,
name: req.body.name,
email: userEmail,
pictureUrl: req.body.picture
}).save(function(err, user) {
if (err) res.send({ errors: err });
const payload = {
facebookId: user.facebookId,
name: user.name,
email: user.email,
pictureUrl: user.picture
};
jwt.sign(payload, secretOrKey, { expiresIn: 3600 }, (err, token) => {
res.json({ success: true, token: "Bearer " + token });
});
return;
});
}
const payload = {
facebookId: user.facebookId,
name: user.name,
email: user.email,
pictureUrl: user.picture
};
jwt.sign(payload, secretOrKey, { expiresIn: 3600 }, (err, token) => {
res.json({ success: true, token: "Bearer " + token });
});
});
});
我非常讨厌我必须使用两次身份验证代码,但它是有效的。如果有人能推荐此代码的重构版本,我们将不胜感激。感谢您的提示。我现在将.save((err,obj)=>{return obj})中的用户作为对象返回。但是,之后仍然无法继续登录过程。@Ruham-好吧,使用带有
.save()
的回调并不容易。这就是为什么我将承诺与let result=wait user.save()一起使用的原因。我提出了一个如何做的建议。如果您想忽略我的建议,这是您的选择,但我向您展示了一种方法。我尝试了您的版本,但由于某种原因(500服务器错误)它不起作用。我发布了工作版本,但我不喜欢现在的代码。@Ruham-好吧,我在回答中说,您必须查看中的结果,让result=wait user.save()
,并找出结果中您的facebook id
的确切位置,因为我自己无法查看数据。看起来在你的版本中,你可以设置user.id=result.backbookId
,然后它就会工作,所以我也编辑了我的。你可以试试。@Ruham-好的,我在回答中更新了我的版本和你的版本的改进版本。我在它丢失的地方添加了一些错误处理。