【问题标题】:How to perform some logic if JWT token is not present in header?如果标头中不存在 JWT 令牌,如何执行一些逻辑?
【发布时间】:2019-09-12 17:56:54
【问题描述】:

我正在使用 passport-jwt 并且有一个端点,如果标头中不存在 jwt 令牌,它应该从数据库返回一些数据。 是否可以应用一些逻辑而不仅仅是发送未经授权的 401?

router.get(
    '/get/items',
    passport.authenticate('jwt', {session: false}),
    (req, res) => {
     // reaches this point only after validating token
     ...
    }
);

因此,如果存在 jwt 令牌,则端点应基于它返回一些数据。如果不是,则应返回 db 中的其他一些数据

【问题讨论】:

    标签: node.js jwt passport-jwt


    【解决方案1】:

    我认为custom callback 是一个选项。它作为最后一个参数传递给authenticate(strategy, options, callback) 方法,它将允许您设置您希望的行为。

    您的代码将如下所示:

    app.get('/get/items', (req, res, next) => {
    
        passport.authenticate('jwt', { session: false }, (err, user, info) => {
            if (!user) {
                /* 
                    Unauthorized accees.
                    Handle here the request as u wish
                */
    
                /* Do some custom logic and return your desired result */
                return res.status(401).json({ success: false, message: 'Unauthorized access!' });
            }
    
            /* User is authorized. Do other stuff here and return your desired result*/
            return res.status(200).json({ success: true, message: 'Congratulations!' });
        })(req, res, next);
        
    });
    

    在此示例中,请注意从内部调用 authenticate() 路由处理程序,而不是用作路由中间件。这给 通过闭包回调访问 req 和 res 对象。

    如果身份验证失败,用户将被设置为 false。如果出现异常 发生,将设置错误。将传递一个可选的信息参数, 包含策略验证提供的其他详细信息 回调。

    回调可以使用提供的参数来处理 验证结果根据需要。请注意,当使用自定义 回调,它成为应用程序的责任建立一个 会话(通过调用 req.login())并发送响应。

    Source

    【讨论】:

      【解决方案2】:

      包装您的中间件并按照您的意愿处理错误:

      function authenticate(req, res, next) {
        passport.authenticate('jwt', { session: false }, (err, user) => {
          if (err) {
            res.status(err.statusCode || 401).json({ error: err.toString() });
            return;
          }
      
          if (!user) {
            res.status(404).json({ ... });
            return;
          }
      
          req.user = user;
      
          next();
        })(req, res, next);
      }
      

      改用它:

      router.get(
          '/get/items',
          authenticate,
          (req, res) => {
           // reaches this point only after validating token
           ...
          }
      );
      

      【讨论】:

        【解决方案3】:

        @codtex 和@Dominic 的回答解决了这个问题。

        我发现以下解决方案也有效:

        router.get(
            '/get/items',
            passport.authenticate('jwt', {session: false}),
            (req, res) => {
                // reaches this point only after validating token
                ...
            },
            (err, req, res, next) => {
                console.log('error handling');
                // reaches this point if validation fails
            }
        );
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-02-09
          • 1970-01-01
          • 2020-06-22
          • 2019-09-16
          • 2019-03-27
          • 2020-06-09
          • 1970-01-01
          • 2013-09-02
          相关资源
          最近更新 更多