0

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

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

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

4

3 回答 3

2

我认为自定义回调是一种选择。它作为最后一个参数传递给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。如果发生异常,将设置 err。将传递一个可选的 info 参数,其中包含策略的验证回调提供的其他详细信息。

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

资源

于 2019-04-23T14:59:12.000 回答
1

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

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
     ...
    }
);
于 2019-04-23T15:01:02.230 回答
0

@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
    }
);
于 2019-04-23T17:27:43.527 回答