2020-12 更新
有一个OAuth 2.1 草案来摆脱隐式流程 - 简短摘要 。OAuth 2.1 汇集了最新的 OAuth 2 最佳实践。
TLDR;如果可以,最好避免隐式流。
更一般地说,为什么“隐式”流程不受欢迎?
因为访问令牌暴露给用户代理(浏览器)。请参阅OAuth 2 规范中的隐式流程图,然后将其与不向用户代理公开令牌的授权代码流程进行比较。
...明确禁止使用带有 id_token 响应类型的“查询”响应模式...为什么禁止?
快速定义:
scheme://host:port/path?query#fragment
URL 的“查询”部分很容易被多方检查 - 它可能被用户代理记录(例如浏览器历史记录),并且经常在 Web 服务器请求日志中找到。经验法则是永远不要通过“查询”参数发送任何敏感信息(例如令牌、授权代码、密码)。
但是,“片段”部分永远不会在 HTTP 请求中发送,也不会出现在 Referer 标头中。只有在用户代理(浏览器)上执行的 JavaScript 才能访问它。
例如,客户端(浏览器)可以发出这样的请求:
GET /authorize?
response_type=id_token%20token
&client_id=s6BhdRkqt3
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
&state=af0ifjsldkj HTTP/1.1
Host: server.example.com
身份验证服务器将响应(注意用“#”表示的“片段”):
HTTP/1.1 302 Found
Location: https://client.example.org/cb#
access_token=SlAV32hkKG
&token_type=bearer
&id_token=eyJ0 ... NiJ9.eyJ1c ... I6IjIifX0.DeWt4Qu ... ZXso
&expires_in=3600
&state=af0ifjsldkj
然后,浏览器在重定向到目标位置时会排除“片段”。浏览器中的 JavaScript 代码应使用更安全的机制(例如 POST 正文)提交相关令牌。
各种浏览器之间存在一些怪癖,但没有任何明显的问题可以违背安全假设。