打字稿输入 http headers

Typescript typing http headers

我对 Typescript 及其类型定义建议感到非常困惑。我正在使用 Apollo Server 执行 Graphql API 并尝试通过请求 headers 使用 JWT 实现授权(我正在重写现有的 API ), 所以首先我从请求中提取令牌 headers 做:

const token: string = req.headers.authorization

但是这样做会引发错误,提示“type string | undefined is not assignable键入 string" 所以我将其更改为:

const token: string | undefined = req.headers.authorization

好的!但在最初的 API 中,他们试图从 req.headers.authorizationreq.headers.Authorization 获得授权道具,我不知道为什么,但我试图做同样的事情:

const token: string | undefined = req.headers.authorization || req.headers.Authorization

并出现新错误:“键入 string | string[] | undefined 不可分配给类型 string | undefined" =21=]

然后我又改成了:

const token: string | undefined | string[] = req.headers.authorization || req.headers.Authorization

我的问题:

1:为什么req.headers.authorization和req.headers.Authorization的数据类型不同?

你的答案是here, in the TypeScript definitions for node's http library.

如你所见,req.headers.authorization是这样定义的:

'authorization'?: string;

因为是可选的,所以可以是undefined。否则,它是 string.

现在寻找 req.headers.Authorization 的定义位置。剧透警告,你不会在列表中找到它。这意味着您必须回顾 req.headers:

的类型定义
interface IncomingHttpHeaders extends NodeJS.Dict<string | string[]> {
  ...other stuff
}

这意味着对于“其他东西”中未定义的任何字符串,类型可以是 undefinedstringstring[].

2:我Google它和所有关于授权的教程都使用req.headers.authorization,那么req.headers.Authorization呢?

根据 HTTP 规范,header 实际上是 case-insensitive。诸如 express(以及在 express 上运行的扩展 ApolloServer)之类的东西默认为你小写,所以你通常应该使用 req.headers.authorization.

奖金

如果您曾使用 apollo-server-lambda,出于某种原因(可能是 AWS 的原因?),大写字母会保留,因此您必须使用 event.headers.Authorization。这意味着如果你打算在一个通用的 space 中做一些可以在不同的 ApolloServer 实现之间交换的事情,你最好在两个地方寻找,接受 undefined | string | string[],然后检查查看它是否是一个数组并使用第一个元素。

不相关[希望有帮助] 语义

const token: string | undefined | string[] = req.headers.authorization || req.headers.Authorization

变量名token技术上不准确。授权 header 应该是 Authorization: <type> <credentials>。如果您要查找“令牌”,它可能在 header 中,在单词 Bearer 之后。不是每个人都遵循这一点,但你通常可以在 space 上拆分并拿走最后一块,除非你真的想要整个 header,在这种情况下,请忽略这一点。