打字稿 jwt.verify 无法访问数据

C T*_*que 5 node.js jwt typescript

我正在尝试将 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
    });
Run Code Online (Sandbox Code Playgroud)

以下是 verify 方法的类型:

export declare function verify(
   token: string,
   secretOrPublicKey: string | Buffer,
): object | string;
Run Code Online (Sandbox Code Playgroud)

短绒错误是:

Property user does not exists on typeof "object|string".
Run Code Online (Sandbox Code Playgroud)

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

链接到图书馆的文档

Nic*_*lle 13

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

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

要修复此错误,请使用any.

return res.send({
    user: (<any>decoded).user
});
Run Code Online (Sandbox Code Playgroud)


Rad*_*iță 6

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

更健壮的方法是声明一个接口来捕获解码令牌的结构并使用它进行转换。

// token.ts
export interface TokenInterface {
  user: {
     email: string;
     name: string;
     userId: number;
  };
}
Run Code Online (Sandbox Code Playgroud)

然后你可以使用

decoded as TokenInterface
Run Code Online (Sandbox Code Playgroud)

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

return res.send({
   user: (decoded as TokenInterface).user
});
Run Code Online (Sandbox Code Playgroud)

笔记:

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