我在ExpressJS中有一个API。在该API中,我有一个登录端点,当发布到该端点时,我不断得到在发送后无法设置标头的异常。
我知道这通常是一个回调,被调用两次或者没有从具有设置标题的东西正确返回,导致应用尝试再次设置它们,但是在我的/login
端点我不这样做
我无法理解为什么会发生这种情况,我希望得到一些意见,因为我接近将我的头发拉出来阅读相同的回复和答案。我希望这是我遗漏的明显事实。
import User from '../../models/user';
import { Router } from 'express';
import jwt from 'jsonwebtoken';
export default () => {
const route = Router();
route.post('/create', async (req, res, next) => {
if (!req.body.email || !req.body.password) {
return res
.status(400)
.json({ message: 'username or password is missing' });
}
const { email, password } = req.body;
const count = await User.count({ email });
if (count > 0) {
return res.status(409).json({ message: 'email must be unique' });
}
const newUser = await new User({ email, password });
const doc = await newUser.save();
return res.status(201).json({ type: 'account', attributes: doc });
});
route.post('/login', async (req, res, next) => {
if (req.body.email && req.body.password) {
const { email, password } = req.body;
const user = await User.findOne({ email });
if (user) {
user.comparePassword(password, isMatch => {
if (isMatch) {
const token = jwt.sign(
{ sub: user.id, roles: [], email: user.email },
process.env.SECRET_KEY,
{ expiresIn: '12h' },
);
return res
.status(200)
.json({ type: 'account', attributes: { token } });
}
});
}
}
res.sendStatus(401);
});
return route;
};
答案 0 :(得分:0)
这里的问题。 comparePassword中的回调仅在该回调内返回。所以代码仍然运行到res.sendStatus(401)
,在回调完成后,它将运行res.status(200).json...
user.comparePassword(password, isMatch => {
if (isMatch) {
const token = jwt.sign(
{ sub: user.id, roles: [], email: user.email },
process.env.SECRET_KEY,
{ expiresIn: '12h' },
);
return res
.status(200)
.json({ type: 'account', attributes: { token } });
}
});
答案 1 :(得分:0)
尝试在用户模型中宣传comparePassword
方法:
userSchema.methods.comparePassword = function (password) {
return new Promise( function(resolve, reject) {
resolve(password === this.password);
});
}
现在您可以使用await
语法来获取承诺结果:
route.post('/login', async (req, res, next) => {
if (req.body.email && req.body.password) {
const { email, password } = req.body;
const user = await User.findOne({ email });
if (user) {
const isMatch = await user.comparePassword(password);
if (isMatch) {
const token = jwt.sign(
{ sub: user.id, roles: [], email: user.email },
process.env.SECRET_KEY,
{ expiresIn: '12h' },
);
return res
.status(200)
.json({ type: 'account', attributes: { token } });
}
}
}
res.sendStatus(401);
});
答案 2 :(得分:0)
import User from '../../models/user';
import { Router } from 'express';
import jwt from 'jsonwebtoken';
export default () => {
const route = Router();
route.post('/create', async (req, res, next) => {
if (!req.body.email || !req.body.password) {
return res
.status(400)
.json({ message: 'username or password is missing' });
}
const { email, password } = req.body;
const count = await User.count({ email });
if (count > 0) {
return res.status(409).json({ message: 'email must be unique' });
}
const newUser = await new User({ email, password });
const doc = await newUser.save();
return res.status(201).json({ type: 'account', attributes: doc });
});
route.post('/login', async (req, res, next) => {
if (req.body.email && req.body.password) {
const { email, password } = req.body;
const user = await User.findOne({ email });
if (user) {
return user.comparePassword(password, isMatch => {
if (isMatch) {
const token = jwt.sign(
{ sub: user.id, roles: [], email: user.email },
process.env.SECRET_KEY,
{ expiresIn: '12h' },
);
return res
.status(200)
.json({ type: 'account', attributes: { token } });
} else {
return res.status(400)
.json({ message: 'username or password is invalid' });
}
});
}
}
res.sendStatus(401);
});
return route;
};
查看
中缺少的更新代码返回 return user.comparePassword(password, isMatch => {
希望它能解决你的问题。