【发布时间】:2018-05-23 10:47:14
【问题描述】:
有点奇怪的问题。我正在构建一个 NodeJS/Express api,使用 json web 令牌为用户进行电子邮件验证。用户注册和电子邮件确认路线的代码如下。在 Postman 中使用以下过程测试这些路由时,一切正常(状态 200,用户对象返回): 1. 发送 POST 请求创建用户。 2. 使用 mongodb shell 从新用户那里获取令牌。 3. 在获取请求到确认路由中使用复制/粘贴的令牌。
但是,当实际单击通过电子邮件发送的链接时,数据库中的所有内容都会按预期更新,但出现 401 错误。即使从电子邮件中的链接复制和粘贴令牌并在邮递员中发送也具有相同的结果。
路线:
app.post('/api/users', (req, res) => {
let body = _.pick(req.body, [
'email', 'password', 'firstName', 'lastName', 'adminRequested'
]);
let user = new User(body);
user.save().then(() => {
return user.generateAuthToken('confirmation', '1h');
}).then((token) => {
let currentUrl = req.protocol + '://' + req.get('host') + req.originalUrl;
let confirmationUrl = currentUrl + `/confirm/${token}`;
mailTransport.sendMail({
from: `Break Board API <${process.env.MAIL_USER}>`,
to: user.email,
subject: 'Your Email Confirmation Link',
text: `Click this link to verify your email: ${confirmationUrl}`
});
res.send(JSON.stringify(user, undefined, 2));
}).catch((e) => {
res.status(400).send(e);
});
});
app.get('/api/users/confirm/:token', confirmToken, (req, res) => {
let token = req.token;
let user = req.user;
req.user.update({
$set: {
emailConfirmed: true
},
$pull: {
tokens: {token}
}
}).then(() => {
res.send(user);
});
});
confirmToken 中间件:
let {User} = require('./../models/user');
let confirmToken = (req, res, next) => {
let token = req.params.token;
User.findByToken(token).then((user) => {
if(!user) {
return Promise.reject();
}
req.user = user;
req.token = token;
next();
}).catch((e) => {
res.status(401).send();
});
};
中间件是整个代码中唯一具有 res.status(401) 的地方,所以我知道它来自哪里,但不明白为什么它只在使用电子邮件中的令牌时发生,或者如果确实是 401,则所有 DB 操作仍然成功。当在 Postman 中使用已修改或不存在的 JWT 令牌强制出现 401 错误时,永远不会执行 DB 操作。
有什么想法吗?
【问题讨论】:
-
所以,通过大量的试验和错误,我弄清楚了发生了什么,但仍然不知道如何解决它。基本上,每当我打开电子邮件时,在我点击链接之前,它都会验证链接。因此,当我单击链接时,所有内容都已更新并且令牌已被删除。
标签: node.js mongodb express json-web-token