typescript jwt.verify无法访问数据

时间:2018-06-07 07:48:56

标签: node.js typescript jwt

我正在尝试将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错误是: typeof“object | string”上不存在属性用户。

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

Link to the documentation of the library

3 个答案:

答案 0 :(得分:1)

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

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

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

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

答案 1 :(得分:1)

创建用户负载界面

import Select from "react-select";

const options = [
  {
    label: "A",
    options: [
      {
        label: "B",
        options: [
          {
            label: "C",
            value: 1
          },
          {
            label: "D",
            value: 2
          },
          {
            label: "G",
            value: 3
          }
        ]
      },
      {
        label: "J",
        options: [
          {
            label: "K",
            value: 4
          },
          {
            label: "L",
            value: 5
          },
          {
            label: "M",
            value: 6
          }
        ]
      }
    ]
  }
];

export const NestedOptGroup = () => <Select name="options" options={options} />

投射到 UserPaylod

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

中间件功能

 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();
};

答案 2 :(得分:0)

您需要投射已解码的令牌。尽管强制转换为 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 类型的对象上的字段。