当使用 Postman 通过授权代码获取访问令牌时,我需要输入的字段之一是Callback URL,也称为重定向 URI 查询参数,当它向授权端点发出请求时。我知道这个 URL 需要在 OAuth 提供程序中注册/列入白名单,但我的问题是,当基于 localhost 时,邮递员如何实际处理/拦截该请求/重定向回来?例如,如果我已经有一个在 http://locahost:8090 上运行的本地服务器,并且我告诉邮递员使用 http://localhost:8090 进行该回调,那么邮递员最终如何看到该请求/重定向回来(到将身份验证代码交换为访问令牌)而不是我的本地 Web 服务器处理该请求?
str*_*y05 14
TL;DR: Postman 在处理响应时基本上会忽略回调 URL。
长话短说
它确实需要它,但仅用于请求。正如您所说,它需要正确 - 与 IdP 客户端应用程序配置完全匹配 - 但仅此而已。
Postman 只是帮助您获取令牌,它不需要将其提供给使用应用程序,这就是重定向 URL 的全部意义 - 客户端应用程序和 OAuth 客户端应用程序已知的静态路径,确保恶意网站/中介不会通过滥用重定向流来窃取令牌。
由于它不适用于互联网上的浏览器,因此 Postman 可以忽略重定向。一旦 IdP 响应令牌,就 Postman 而言,就可以开始了。它可以将令牌保存在本地令牌存储中并使用它来发出 API 请求。
隐式流程
当我单击“请求令牌”时,Postman 会发出如下请求:
GET https://exampleendpoint.okta.com/oauth2/default/v1/authorize?nonce=heythere&response_type=token&state=state&client_id={the_client_id}&scope=profile%20openid&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fimplicit%2Fcallback
Run Code Online (Sandbox Code Playgroud)
Postman 弹出浏览器以向/authorize端点发出此请求,然后 IdP 在端点上创建令牌(如果浏览器已有 cookie),或者执行各种重定向以对用户进行身份验证,然后创建令牌。
在此流程结束时,Postman 将从包含令牌(在位置标头上)的 IdP 接收 302。该重定向的目标是 IdP 中配置的重定向 URL:
302
Location: http://localhost:8080/implicit/callback#access_token=eyJraWQiOiJxOGRmTGczTERCX3BEVmk4YVBrd3JBc3AtMFU1cjB6cXRUMFJveFZRUVVjIiwiYWxnIjoiUlMyNTYifQ.{the_rest_of_the_token}&token_type=Bearer&expires_in=3600&scope=profile+openid&state=state
Run Code Online (Sandbox Code Playgroud)
此时,Postman 从 #access_token 参数中获取令牌,一切顺利。
授权码流程
授权码流程有两种:
身份验证代码流程被认为比隐式流程“更好”,因为它需要流程中的第二步来获取访问令牌。您点击授权,这会为客户端提供一个代码,然后用该代码交换令牌。此令牌代码为服务器端组件提供了更多机会执行更多操作 - 额外检查、丰富令牌和各种其他操作。
问:为什么有 2 个授权码流程?答:这样做的问题是它需要一个服务器端组件,而许多 SPA 和/或移动应用程序不想托管该组件。接收代码并获取令牌的端点必须维护凭据 - 客户端 ID 和客户端密钥 - IdP 在创建令牌时需要这些凭据。PKCE 是一种扩展,消除了对受信任服务器的要求。它将计算出的哈希值添加到 IdP 记住的 /authorize 调用中,然后在随后对 /token 的调用中,客户端提供哈希值的源值。服务器执行相同的计算,检查它与原始请求中的计算是否相同,然后确信它没有将令牌分发给坏人。
使用 PKCE 验证代码
就重定向而言,这与隐式重定向完全相同。但对于请求,它需要发出第二次请求来交换令牌的代码。这里的主要区别是
现请求如下:
GET https://exampleendpoint.okta.com/oauth2/default/v1/authorize?nonce=heythere&response_type=code&state=state&client_id={client_id}&scope=profile%20openid&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fimplicit%2Fcallback&code_challenge=E7YtiHqJRuALiNL_Oc5MAtk5cesNh_mFkyaOge86KXg&code_challenge_method=S256
Run Code Online (Sandbox Code Playgroud)
Postman 将弹出浏览器(如果需要,IdP 将通过登录重定向它)
最终的代码响应也是 302,但是location标头包含代码而不是令牌:
location: http://localhost:8080/implicit/callback?code=J3RlQqW122Bnnfm6W7uK&state=state
Run Code Online (Sandbox Code Playgroud)
所以现在客户端需要调用“Access Token URL”字段中定义的端点来获取令牌:
POST https://exampleendpoint.okta.com/oauth2/default/v1/token
Body:
grant_type: "authorization_code"
code: "J3RlQqW122Bnnfm6W7uK"
redirect_uri: "http://localhost:8080/implicit/callback"
code_verifier: "Fqu4tQwH6bBh_oLKE2zr0ijArUT1pfm1YwmKpg_MYqc"
client_id: "{client_id}"
client_secret: ""
Run Code Online (Sandbox Code Playgroud)
响应是一个很好的旧 200,不会重定向 - 授权调用将客户端发送回最终重定向登录页面,而 POST 只是一个普通请求,响应中带有令牌
{"token_type":"Bearer","expires_in":3600,"access_token":"eyJraWQiOiJxOGRmTGczTERCX3BEVmk4YVBrd3JBc3AtMFU1cjB6cXRUMFJveFZRUVVjIiwiYWxnIjoiUlMyNTYifQ.*******","scope":"profile openid","id_token":"eyJraWQiOiJxOGRmTGczTERCX3BEVmk4YVBrd3JBc3AtMFU1cjB6cXRUMFJveFZRUVVjIiwiYWxnIjoiUlMyNTYifQ.********"}
Run Code Online (Sandbox Code Playgroud)