打字稿输入 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.authorization
或 req.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
我的问题:
- 为什么
req.headers.authorization
和 req.headers.Authorization
有不同的数据类型?
- 我Google它和所有关于授权的教程都使用
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
}
这意味着对于“其他东西”中未定义的任何字符串,类型可以是 undefined
、string
或 string[]
.
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,在这种情况下,请忽略这一点。
我对 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.authorization
或 req.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
我的问题:
- 为什么
req.headers.authorization
和req.headers.Authorization
有不同的数据类型? - 我Google它和所有关于授权的教程都使用
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
}
这意味着对于“其他东西”中未定义的任何字符串,类型可以是 undefined
、string
或 string[]
.
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,在这种情况下,请忽略这一点。