使用 oAuth 2.0,在“authorization-code”授权授予中,我首先调用“/authorize”,获取代码,然后在调用“/token”中使用此代码来获取访问令牌。
我的问题:为什么这是流程?我想这是出于安全原因,但我无法弄清楚。为什么是这样实现的,而不是在第一次调用(“/authorize”)后立即获得访问令牌?
为什么我们需要这个代码?
使用 oAuth 2.0,在“authorization-code”授权授予中,我首先调用“/authorize”,获取代码,然后在调用“/token”中使用此代码来获取访问令牌。
我的问题:为什么这是流程?我想这是出于安全原因,但我无法弄清楚。为什么是这样实现的,而不是在第一次调用(“/authorize”)后立即获得访问令牌?
为什么我们需要这个代码?
是否也可以通过此中间步骤阻止客户端查看访问令牌?
来自 O'Reilly 的书:
授权代码此授权类型最适合服务器端 Web 应用程序。在资源所有者授权访问他们的数据后,他们将被重定向回 Web 应用程序,并使用授权代码作为 URL 中的查询参数。客户端应用程序必须将此代码交换为访问令牌。这种交换是服务器到服务器完成的,并且需要 client_id 和 client_secret,甚至阻止资源所有者获取访问令牌。此授权类型还允许使用刷新令牌对 API 进行长期访问。
基于浏览器的客户端应用程序的隐式授权 隐式授权是所有流程中最简单的,并且针对在浏览器中运行的客户端 Web 应用程序进行了优化。资源所有者授予对应用程序的访问权限,然后立即生成新的访问令牌并使用 URL 中的 #hash 片段将其传递回应用程序。应用程序可以立即从哈希片段中提取访问令牌(使用 JavaScript)并发出 API 请求。这种授权类型不需要中间的“授权代码”,但它也不会为长期访问提供可用的刷新令牌。
更新 - 确实是:
什么时候应该使用授权码流?授权码流程应在以下情况下使用
需要长期访问。
OAuth 客户端是一个 Web 应用程序服务器。
API 调用的问责制非常重要,并且 OAuth 令牌不应该泄露给用户可以访问它的浏览器。
更多的:
也许最重要的是——因为访问令牌永远不会通过浏览器发送——访问令牌通过浏览器历史记录、引用标头、JavaScript 等泄露给恶意代码的风险较小。
授权码流适用于涉及 3 方的场景。
这些政党是:
客户
用户使用他的网络浏览器。他想使用你的应用程序。
提供者
有关于用户的信息。如果有人想访问这些数据,用户必须先同意。
您的(网络)应用程序
想要从提供商处访问有关用户的信息。
现在您的应用程序对用户说(将他的浏览器重定向到/authorize
端点):
嘿用户,这是我的客户 ID。请与提供者交谈,并允许他直接与我交谈。
因此,用户与提供者对话(请求授权码并通过在浏览器中打开您的回调 URL 将其返回给您的应用程序):
嘿供应商,我想使用这个应用程序,所以他们需要访问我的数据。给我一些代码,我将此代码提供给应用程序。
现在您的应用程序具有客户端和提供者已知的授权代码。通过将其交给提供商,您的应用现在可以证明客户端允许它访问他的数据。提供商现在向您的(网络)应用程序颁发访问令牌,因此您的(网络)应用程序不必每次都重做这些步骤(至少在一段时间内)。
如果您的应用程序直接在客户端运行(例如 iPhone/Android 应用程序或 Javascript 客户端)的其他应用程序类型,则中间步骤是多余的。
客户端的数据通常被认为是不安全的。在初始步骤本身授予令牌的隐式调用的情况下,任何拥有 access_token 的人都可以请求数据,API 不知道谁在调用该 API。
但是,对于应用程序想要标识自己的 Web 服务器应用程序,带有 client_secret 的 client_id 与 authentication_code 一起发送以获取 access_token,将来可以独立发送。
假设,如果 access_token 最初是自己授予的,那么 client_id 和 access_token 仍然会被认为是公开的,所以应用程序必须每次都发送 client_secret 和 access_token 以确保请求确实来自它。
而在当前场景下,获取access_token后,可以独立进行进一步的请求,而不需要client_secret。
我认为是这样的;
当我们使用授权码时,我们有2个验证部分;
因此,如果我们在用户进行身份验证时返回访问令牌而不是授权码,我们知道是用户请求它,但我们不知道它将用于注册的客户端。例如,您的网络应用程序。
当我们使用“隐式授权”时;(或返回访问令牌而不是授权码)
重要的一点是
也许最重要的是——因为访问令牌永远不会通过浏览器发送——访问令牌通过浏览器历史记录、引用标头、JavaScript 等泄露给恶意代码的风险较小。
@ksht 的回答基本上是正确的。对于那些寻找简单、简短答案的人来说,它是这样的:
因为客户端应用程序(浏览器或本机应用程序)可以拦截传递的令牌。oauth隐式流程确实允许这样做,但仅在非常特定的情况下。在所有其他情况下,浏览器可能会泄漏信息(操作系统中的黑客攻击、浏览器错误、插件),或者对于本机应用程序,您可以拦截将重定向 url 映射到应用程序的自定义 url 方案。因此,解决方法是发回代码而不是令牌(通过 tls)并使用 PKCE 确保代码可以安全地交换为令牌。