【问题标题】:typescript jwt.verify cannot access datatypescript jwt.verify 无法访问数据
【发布时间】:2018-11-17 00:59:10
【问题描述】:

我正在尝试将 JWT 与 nodejs 一起使用。 我的问题是我无法从 JWT 验证函数中读取数据。 我是这样使用它的:

//encode when logging in
const token = jwt.sign(
    { user: user },
    'secret'
);


// decode when fetching the user from token
const decoded = jwt.verify(req.body.jwtToken, 'secret');
    return res.send({
         user: decoded.user // <-- error here
    });

这里是验证方法的类型:

export declare function verify(
   token: string,
   secretOrPublicKey: string | Buffer,
): object | string;

linter 错误是:

Property user does not exists on typeof "object|string".

我应该如何从解码的令牌中获取数据?

Link to the documentation of the library

【问题讨论】:

  • 请添加您正在使用的 jwt-library 的名称。
  • 我已将其添加到说明中

标签: node.js typescript jwt


【解决方案1】:

在使用 Typescript 时,您必须记住所有内容都是键入的,例如Java 或 C#。 object 是一个不知道 user 属性的超类。

虽然此代码在 javascript 中有效(您正在查看 javascript 文档),但它不在 typescript 中。

要修复此错误,请使用 any 转换解码后的令牌。

return res.send({
    user: (<any>decoded).user
});

【讨论】:

  • 谢谢!如果拒绝“任何”,请指定类型:(extractedToken).email
  • 虽然我的方法效果很好并且不费吹灰之力,但我建议您使用 Radu Diță 提供的方法。即使这意味着更多的工作,它也可以最终消除编写错误。
  • @NicoVanBelle 很抱歉投了反对票。但是使用 并不是最好的解决方案:)
  • @sunnyarya 这确实是我在我的 cmets 中所说的。有更好的方法,但它们需要额外的努力
【解决方案2】:

您需要投射解码后的令牌。尽管转换为 any 会起作用,但您也会失去对该变量的类型检查。

一种更强大的方法是声明一个接口,它可以捕获已解码令牌的结构并使用它进行转换。

// token.ts
export interface TokenInterface {
  user: {
     email: string;
     name: string;
     userId: number;
  };
}

然后你可以使用

decoded as TokenInterface

或者更确切地说是你的情况

return res.send({
   user: (decoded as TokenInterface).user
});

注意事项:

  1. 转换是在编译时完成的,而不是运行时
  2. 创建接口还有一个额外的好处,就是您可以将类型定义保存在一个地方。如果您想将特定类型的字段添加到现有对象,这将特别有用。这方面的一个示例是将令牌作为字段添加到 express.Request 类型的对象上。

【讨论】:

    【解决方案3】:

    创建用户负载接口

    interface UserPayload {
      id: string;
    }
    interface JwtExpPayload {
      expiresIn: string;
      exp: number;
    }
    

    投射到 UserPaylod

     try {
        const jwtPayload = jwt.decode(
          req.header('authorization')!
        ) as JwtExpPayload;
    
        req.jwtPayload = jwtPayload;
    
        const payload = jwt.verify(
          req.header('authorization')!,
          process.env.JWT_KEY!
        ) as UserPayload;
    
        req.currentUser = payload;
      } catch (err) {
        console.log(err);
      }
    

    中间件函数

    export const requireAuth = (
      req: Request,
      res: Response,
      next: NextFunction
    ) => {
      if (req.jwtPayload && Date.now() >= req.jwtPayload!.exp * 1000) {
        throw new TokenExpiredError();
      }
      if (!req.currentUser) {
        throw new NotAuthorizedError();
      }
    
      next();
    };
    
    
     const userJwt = jwt.sign(
        {
          id: existingUser.id,
        },
        process.env.JWT_KEY!,
        { expiresIn: 30 }
      );
    

    【讨论】:

      猜你喜欢
      • 2015-05-13
      • 2017-12-10
      • 1970-01-01
      • 2021-03-12
      • 2016-07-02
      • 1970-01-01
      • 2022-12-04
      • 1970-01-01
      相关资源
      最近更新 更多