TL;DR:标准之间不存在冲突。 OAuth 访问令牌可以一般来说包含任何可打印的 ASCII 字符,但是if访问令牌是承载令牌,它必须使用“token64”语法才能兼容 HTTP/1.1。
RFC 6749,§1.4 https://www.rfc-editor.org/rfc/rfc6749#section-1.4告诉我们:“访问令牌是一个字符串”并且“通常对客户端来说是不透明的”。§A.12 https://www.rfc-editor.org/rfc/rfc6749#appendix-A.12将其定义为一个或多个可打印 ASCII 字符 ([ -~]+
在正则表达式中)。
RFC 6749 定义了各种方法获得一个访问令牌,但并不关心如何实际use访问令牌,而不是说您将其“呈现”给资源服务器,资源服务器必须验证然后接受或拒绝它。
但 RFC 6749 确实要求授权服务器告诉客户端代币类型(另一个字符串),客户端可以使用它来确定how使用访问令牌。
A 代币类型string 是 IANA 注册的类型名称(例如Bearer
or mac
),或供应商 URL(例如http://oauth.example.org/v1
),尽管 URL 只是一个方便的命名空间标识符,并且不必解析为任何内容。
在大多数部署中,令牌类型为Bearer
,其语义在 RFC 6750 中定义。
RFC 6750 定义three向资源服务器提供承载访问令牌的方法 (§§2.1–2.3)。这受到推崇的方法(哪个资源服务器must支持符合标准)的方法是在 HTTP 授权标头中发送它(§2.1 https://www.rfc-editor.org/rfc/rfc6750#section-2.1),在这种情况下,令牌必须是“b64token”([-a-zA-Z0-9._~+/]+=*
在正则表达式中)。
这与 HTTP/1.1 规范所称的“token68”相匹配(RFC 7235 §2.1 https://www.rfc-editor.org/rfc/rfc7235#section-2.1),并且对于允许在 HTTP 授权标头中不加引号地使用令牌是必要的。 (至于为什么 HTTP/1.1 允许这些确切的字符,这可以归结为与 HTTP/1.0 和基本身份验证标准相关的历史原因,以及当前和历史 HTTP 实现的限制。网络协议是一件混乱的事情。)
一个“b64token”(aka“token68”)允许通常与 Base64 编码一起使用的 ASCII 字符子集,但是(尽管有名称)承载令牌不强加任何 base64 语义 http://w3-org.9356.n7.nabble.com/p7-rename-b64token-to-token68-to-avoid-misunderstandings-td108256.html。它只是客户端从一台服务器接收并传递到另一台服务器的不透明字符串。实现可以为其分配语义(例如JWT https://en.wikipedia.org/wiki/JSON_Web_Token),但这超出了 OAuth 或不记名令牌标准。
RFC 6750 没有规定如果与其他两种(不推荐)方法一起使用,承载访问令牌必须是 b64token,但考虑到客户端应该能够选择该方法,因此给出没有多大意义它是一个非 b64token 令牌。
其他 OAuth 令牌类型可能不依赖于在 HTTP 标头中不加引号地传递(或者它们可能根本不使用 HTTP),因此可以自由使用任何可打印的 ASCII 字符。这可能例如对于令牌类型很有用not对客户不透明;作为一个例子,我目前正在处理一个设置,其中访问令牌响应看起来有点像这样:
{
"access_token": "{\"endpoint\": \"srv8.example.org\", \"session_id\": \"fafc2fd\"}",
"token_type": "http://vendor.example.org/",
"expires_in": 3600,
"refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA"
}
这里,访问令牌是 JSON 编码的数据结构,客户端必须根据该数据结构进行操作(根据与供应商令牌类型关联的规则)才能访问受保护的资源。