如果标头中不存在 JWT 令牌,如何执行一些逻辑?

Posted

技术标签:

【中文标题】如果标头中不存在 JWT 令牌,如何执行一些逻辑?【英文标题】:How to perform some logic if JWT token is not present in header? 【发布时间】: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 中的其他一些数据

【问题讨论】:

【参考方案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
    
);

【讨论】:

以上是关于如果标头中不存在 JWT 令牌,如何执行一些逻辑?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 api 请求标头中插入 api 身份验证所需的 jwt 令牌?

Spring Webflux SecurityValidate OAuth2 JWT 令牌

使用AWS Android SDK发送JWT令牌

如何在客户端上保存 JWT 令牌,在节点中使用 Hapi js。?

关于 JWT(服务器端和客户端)的一些基本问题

响应标头中缺少 jwt 授权令牌