【问题标题】:next() middleware not working with token authenticationnext() 中间件不适用于令牌身份验证
【发布时间】: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") 或其他内容的响应。
  • 非常感谢您的帮助!我尝试了你的想法,但没有奏效我最终以不同的方式修复它

标签: node.js reactjs express middleware next


【解决方案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 调用返回错误时),您的代码仍然显示“您的帐户已确认”。
  • 谢谢,如果一切顺利,我将该消息更改为从后端发送
猜你喜欢
  • 2015-09-14
  • 1970-01-01
  • 2020-10-15
  • 2019-07-11
  • 2017-03-15
  • 2019-11-24
  • 1970-01-01
  • 2016-08-04
  • 2021-01-25
相关资源
最近更新 更多