next() 中间件不适用于令牌身份验证
Posted
技术标签:
【中文标题】next() 中间件不适用于令牌身份验证【英文标题】:next() middleware not working with token authentication 【发布时间】:2020-04-04 00:37:12 【问题描述】:我正在使用电子邮件身份验证进行帐户注册,我在 URL 上发送一个令牌,然后我使用 useParams 从 URL 获取令牌并将其传递给后端以最终验证用户的帐户。
问题是在后端的身份验证中间件上,next() 回调没有继续该过程。
中间件成功解析/解码令牌(因为它显示了存储在其中的用户 ID),当调用 next() 时,一切都停止,不给出任何错误,什么都没有。当我发出 GET 请求时会发生这种情况,如果我发出 POST 请求,它会返回令牌无效,这是不正确的。
前端请求:
const Confirmation = () =>
const [popMessage, setPopMessage] = useState('');
let params = useParams("/confirm/:token");
const token = params;
const confirmAcc = async () =>
try
const config =
headers:
'x-auth-token': token,
await axios.get('/api/auth/confirm/', config)
.catch(err=>
console.error(err.response);
)
setPopMessage('Your account has been confirmed');
// setTimeout(() => window.location.href = '/login';, 3500);
catch (err)
console.log(err.response.data);
return;
后端路由器:
router.get('/confirm/', auth, async (req, res) =>
console.log('Im here!!')
try
console.log('Im here too!!')
const user = await User.findById(req.user.id).select('-password');
console.log('user', user)
await user.update( confirmed: true );
sendEmail(user.email, user.name, "welcome");
catch (err)
res.status(401).send('your email token is invalid');
return;
);
中间件“身份验证”:
module.exports = function(req, res, next)
const token = req.header('x-auth-token');
if (!token)
return res.status(401).send('No token, authorization denied ');
try
const decoded = jwt.verify(token, config.get('jwtSecret'));
console.log('decoded:', decoded)
req.user = decoded.user;
next();
catch(err)
res.status(401).send('Token is not valid');
最奇怪的事情:它只发生在这个路由器上,应用程序的其余部分使用相同的确切代码工作正常。如果有人能分享任何想法,我将不胜感激。
提前致谢!
【问题讨论】:
我看到的一件事是,您的router.get("/confirm", ...)
路由在成功时不会对请求发送任何类型的响应。它只是发送电子邮件,但不会将任何内容作为 http 响应发送回客户端。 auth()
中间件对我来说看起来不错。
您确定jwt.verify(token, ...)
解码为整个用户对象吗?
此外,客户端代码中的axios()
调用调用setPopMessage('Your account has been confirmed');
,即使出现错误也是如此。但是,在成功的情况下,因为 axios()
调用永远不会完成,因为您从未从服务器发送响应,所以 await axios()
将永远存在(除非出现错误)。因此,您需要发送来自客户端res.send("ok")
或其他内容的响应。
非常感谢您的帮助!我尝试了你的想法,但没有奏效我最终以不同的方式修复它
【参考方案1】:
问题在于请求的类型:我更改为 PUT 请求并在请求中发送一个空正文。修复了它,这里是代码:
const Confirmation = () =>
const [popMessage, setPopMessage] = useState('');
let params = useParams("/confirm/:token");
const token = params;
const confirmAcc = async () =>
try
const config =
headers:
'x-auth-token': token,
// here, empty body and PUT req.
const body = null
axios.put('/api/auth/confirm/',body, config)
.catch(err=>
console.error(err.response);
);
setPopMessage('Your account has been confirmed');
setTimeout(() => window.location.href = '/login';, 3500);
catch (err)
console.log(err.response.data);
return;
;
【讨论】:
即使没有确认(当 axios 调用返回错误时),您的代码仍然显示“您的帐户已确认”。 谢谢,如果一切顺利,我将该消息更改为从后端发送以上是关于next() 中间件不适用于令牌身份验证的主要内容,如果未能解决你的问题,请参考以下文章