【问题标题】:JavaScript conditonal statement behaving differentlyJavaScript 条件语句表现不同
【发布时间】:2020-06-02 10:32:33
【问题描述】:

我有一个端点localhost:3000/users/add 和localhost:3000/users/login。当用户登录服务器时,将返回一个 Jsonwebtoken,其中包含以下格式的两个属性:user: { username: 'user_name', access_level: 4 }。然后我有一个auth 自定义中间件来验证用户的access_level,我用它来保护localhost:3000/users/add。然后路线如下所示:

router.js:

router.post('/add', auth, async (req, res, next) => {
    // get user input
    const user = req.body;
    try {
        const data = await Helper.validateUserInput(user)

        // encrypt password
        const hash = await Helper.encryptPassword(data.value.password)
        if(hash) {
            const databaseUser = new User({
                'username': data.value.username,
                'password': hash,
                'access_level': data.value.access_level
            });
            // persist to database
            const saved = await databaseUser.save();
            console.log(saved);
            res.status(200).json({success: true, message: `User successfully added`})

        }

    }
    // if there's an error
    catch(error){
        if(error.hasOwnProperty('code')) {
            const error_code = error.code;
            if(error_code === 11000) {
                return res.status(400).json({
                    success: false, 
                    error_message: error.errmsg
                })
            }else {
                return res.status(500).json({
                    success: false, 
                    error: error
                })
            }
        }  
    }      
});

auth中间件函数如下:

auth.js:

const Helper = require('../helpers/helpers')

module.exports = function async (req, res, next) {
    const token = req.query.token;
    if(!token) {
        res.status(403).json({
            success: false,
            error_message: `Forbiden - Invalid credentials!`
        })
    }
    Helper.verify_token(token)
    .then((user) => {
        const { access_level } = user.user;
        console.log(access_level)
        if(access_level != 4) {
            res.status(401).json ({
                success: false,
                error_message: `Unauthorized - Invalid credentials!`
            })
        }else {
            next()
        }
    })
    .catch((err) => {
        res.status(403).json({
            success: false,
            error_message: `Forbiden - Invalid credentials!`
        })
    })
}

然后我尝试访问受保护的路由,但 Postman 只是挂起并且没有给出响应。奇怪的是,如果我在auth.js中更改if statement,例如:

if(access_level != 1) {
   res.status(401).json ({
      success: false,
         error_message: `Unauthorized - Invalid credentials!`
      })
   }else {
     next()
 }

一切正常。我真的不明白这是什么问题。

【问题讨论】:

  • 好的,access_level 的值会影响结果。是否有其他路线响应请求?
  • 语句中的任何其他条件都有效,但是,特定条件 if (access_level != 4) 无效
  • 尝试在 if(hash) 的 else 中给出响应。可能返回的哈希是未定义的或错误的,并且没有其他块,所以邮递员一直挂到响应。
  • 请问您发送的数据是什么?因为如果您发送 4 作为访问级别,那么当它工作时,它会通过 else 语句处理,当它挂起时,它会通过 if 语句处理
  • 你能像这样在res.status(401)前面加上return然后再试一次吗? return res.status(401)

标签: javascript node.js express jwt postman


【解决方案1】:

改变添加功能

router.post('/add', auth, async (req, res, next) => {
    // get user input
    const user = req.body;
    try {
        const data = await Helper.validateUserInput(user)

        // encrypt password
        const hash = await Helper.encryptPassword(data.value.password)
        if (hash) {
            const databaseUser = new User({
                'username': data.value.username,
                'password': hash,
                'access_level': data.value.access_level
            });
            // persist to database
            const saved = await databaseUser.save();
            console.log(saved);
            return res.status(200).json({ success: true, message: `User successfully added` })
        } else {
            return res.status(500).json({
                success: false,
                error: "Please try again"
            })
        }

    }
    // if there's an error
    catch (error) {
        if (error.hasOwnProperty('code')) {
            const error_code = error.code;
            if (error_code === 11000) {
                return res.status(400).json({
                    success: false,
                    error_message: error.errmsg
                })
            } else {
                return res.status(500).json({
                    success: false,
                    error: error
                })
            }
        }
        else {
            return res.status(500).json({
                success: false,
                error: error
            })
        }
    }
});

并更改身份验证中间件

const Helper = require('../helpers/helpers')

module.exports = function async (req, res, next) {
    const token = req.query.token;
    if(!token) {
        res.status(403).json({
            success: false,
            error_message: `Forbiden - Invalid credentials!`
        })
    }
   else{
    Helper.verify_token(token)
    .then((user) => {
        const { access_level } = user.user;
        console.log(access_level)
        if(access_level != 4) {
            res.status(401).json ({
                success: false,
                error_message: `Unauthorized - Invalid credentials!`
            })
        }else {
            next()
        }
    })
    .catch((err) => {
        res.status(403).json({
            success: false,
            error_message: `Forbiden - Invalid credentials!`
        })
    })
  }
}

【讨论】:

  • 我看不出我的逻辑有什么不同?你能详细说明一下吗
  • Kimar 另一件事会引发错误,else statement 在try catch 之后
  • 1.如果 Helper.encryptPassword(data.value.password) 失败,您没有处理,您只检查代码是否存在错误,如果代码不存在错误怎么办。 2. 在身份验证中间件中,如果令牌存在或不存在,仍然会执行验证,因为您刚刚添加了 !token
  • 这是一个普通对象,有两个属性{ user: { username: 'user_name', access_level: 4 } }
猜你喜欢
  • 2022-07-07
  • 2023-03-21
  • 1970-01-01
  • 2011-05-04
  • 2011-09-25
  • 1970-01-01
  • 2021-01-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多