Passport JWT 适用于空有效负载

Posted

技术标签:

【中文标题】Passport JWT 适用于空有效负载【英文标题】:Passport JWT works with empty payload 【发布时间】:2019-10-14 01:55:50 【问题描述】:

我已经为 JWT 初始化了策略:

const jwtStrategyOptions = 
  jwtFromRequest: ExtractJwt.fromHeader('x-access-token'),
  secretOrKey: 'publicKey',


passport.use(
  new JwtStrategy(
    jwtStrategyOptions,
    (payload, done) => 
      mysql.Users.readOne(['id'],  id: payload.userId )
      .fork(
        error => console.log(error)
          done(error),
        user => 
          console.log(user)
          done(null, user)
      )
    
  )
)

和中间件:

const isAuthenticated: RequestHandler = (req, res, next) => 
  passport.authenticate(
    'jwt',
     session: false, failWithError: true ,
    (error, user) => 
      //error is null when I pass empty payload
      if (error) 
        return next(error)
      
      req.user = user

      return next()
    
  )(req, res, next)

但是当我传递空或无效的令牌 Passport 时,只需传递这个

(payload, done) => 
  MySQL.Users.readOne(['id'],  id: payload.userId )
  .fork(
    error => console.log(error)
      done(error),
    user => 
      console.log(user)
      done(null, user)
  )

步骤和代码执行next() 函数。 我能以某种方式检测到有效载荷无效或为空吗?

【问题讨论】:

【参考方案1】:

我不太确定 MySQL 调用返回类型,但如果没有与 id 匹配的内容,是否会引发错误?

(payload, done) => 
  MySQL.Users.readOne(['id'],  id: payload.userId )
  .fork(
    error => console.log(error)
      done(error),
    user => 
      console.log(user)
      done(null, user)
  )

如果它没有引发错误但返回 null 或空值,则需要在 'success' 回调函数中检查它,因为在这种情况下,它会以空值调用 done(null, user)

根据您的评论,我用来检查令牌过期错误的一些代码可能会有所帮助:

    passport.authenticate('jwt',
        session: false,
        //we need this callback to return information on why it's failing
        //err is not populated, but 'info' is...
        (err, user, info) => 
            if (err) 
                return next(err);
            

            //if we couldn't authenticate the user, check why
            //401 is used when no token or random information is provided
            //403 is used when a well-formed token is provided, but it has expired thus not valid anymore
            if (!user) 
                if (info.name === 'TokenExpiredError') 
                    return res.status(403).send(info.name);
                
                else 
                    return res.status(401).send(info.message);
                
            

            req.user = user;

            return next();

【讨论】:

当我传递有效令牌时,一切正常,我从 db 获取用户,但是当我传递无效或空令牌时,它只是跳过带有 DB 选择的回调函数,并且在 passport.authenticate 方法中出错等于 null。 好的,我知道了,我更新了我的答案。希望它有所帮助:D 我有点困惑,为什么在有 TokenExpiredError 时没有填充错误?不应该被视为错误吗?我目前正在尝试拦截令牌是否已过期并且错误始终为空,但信息显示某些内容有错误,就像您的代码一样。 @The.Wolfgang.Grimmer 我认为err 对象在身份验证函数中存在实际错误时使用,info 是有关令牌数据的详细信息。就解析等而言,过期的令牌仍然是“有效”令牌...... @HRK44 是的,但这有点不直观。如果 jsonwebtoken 包在后台抛出的错误被捕获会更好

以上是关于Passport JWT 适用于空有效负载的主要内容,如果未能解决你的问题,请参考以下文章

我在我的 nestJS 应用程序(使用 authGuard)中使用了 passport-jwt 身份验证策略,如何访问我的控制器中的令牌有效负载?

ExpressJS - JWT 和 Passport 实现

更新存储在 jwt 有效负载中的字段

使用 passport-jwt 进行 JWT 身份验证不考虑到期日期

完全相同的 package.json 文件适用于空的全新项目,但不适用于旧项目

加密 JWT 有效负载