OAuth2

发布时间 2023-11-17 16:59:00作者: archaique

参考:

 

为了对 OAuth2 有一个直观的认识。我们先从一个例子开始。

谷歌的 OpenId Connect 是 OAuth2 的一个实践,集成了谷歌 OpenId Connect 的网站,可以实现用谷歌账号登录它们的网站,比如说我们熟悉的 StackOverflow 就可以集成了 OpenId Connect (谷歌还有一个叫 Sign in with Google 的客户端 SDK,虽然也是基于 OAuth2,但是经过了封装和标准协议还是有些区别。比如 Reddit 等网站谷歌账号登录就是用的这个 SDK 。为了阐述标准的 OAuth2,今天我们还是用使用  OpenId Connect  的 StackOverflow 来做说明)。

如果我们之前已经用谷歌账号登录过 StackOverflow,可以先将浏览器 Cookie 缓存清除。再打开 StackOverflow 网站。

用谷歌账号登陆前 StackOverflow,打开 F12 Network,并选中 Preserve log,这样在网页重定向之后,之前的请求记录仍然会保留下来。

 完成用谷歌账号登录后,我们来一一分析在这期间发生的请求

 

在阅读下面的步骤之前,请保证已经了解了什么是重定向——《》

 

我们从浏览器可以看到的相关请求有:

1、用户点击谷歌账号进行登录,returnurl 是用户现在停留的页面,我停留在 StackOverflow 首页。

https://stackoverflow.com/users/login?
  ssrc=head
  &returnurl=https://stackoverflow.com/

 

{
  "fkey": "0e092d8da5b2ef159f31ca6e96b702bed161d848e75e108b5619adeb57f62b49",
  "ssrc": "head",
  "email": "",
  "password": "",
  "oauth_version": "2.0",
  "oauth_server": "https://accounts.google.com/o/oauth2/auth"
}

StackOverFlow 后端返回谷歌的 OAuth2 接口,自己的 client_id,以及 redirect_uri 是到谷歌授权服务器的 url

Status Code: 302 Found
Location: https://accounts.google.com/o/oauth2/auth?
  client_id=717762328687-iludtf96g1hinl76e4lc1b9a82g457nn.apps.googleusercontent.com
  &scope=profile email
  &redirect_uri=https://stackauth.com/auth/oauth2/google
  &state=
  {
"sid":1,"st":"59:3:1b8,16:c4729f2f7e47e8e0,10:1700192426,16:9b919914a5835436,ab53156abc79d1c3efbfbd96539ee08ce612452f12f2862ff35bb6c82ad2f805","cid":"717762328687-iludtf96g1hinl76e4lc1b9a82g457nn.apps.googleusercontent.com","k":"Google","ses":"272ab7f4f4cd4640b68720f3c05770f5"}   &response_type=code

2、浏览器收到上面的 302 后,就会用 Location 里的 url 再发出一次请求。这样就会带上 client_id 和 redirect_uri 请求到谷歌授权服务器

https://accounts.google.com/o/oauth2/auth
  ?client_id=717762328687-iludtf96g1hinl76e4lc1b9a82g457nn.apps.googleusercontent.com
  &scope=profile email
  &redirect_uri=https://stackauth.com/auth/oauth2/google
  &state=
  {
"sid":1,"st":"59:3:1b8,16:c4729f2f7e47e8e0,10:1700192426,16:9b919914a5835436,ab53156abc79d1c3efbfbd96539ee08ce612452f12f2862ff35bb6c82ad2f805","cid":"717762328687-iludtf96g1hinl76e4lc1b9a82g457nn.apps.googleusercontent.com","k":"Google","ses":"272ab7f4f4cd4640b68720f3c05770f5"}   &response_type=code

谷歌授权服务器的响应是 302 重定向

    • 当需要客户同意授权时,返回的重定向地址是谷歌的授权页面。客户点击同意后会在后面会再重定向到 StackOverflow 设置的 redirect_url 后端地址
    • 当不需要客户同意授权时,返回的重定向地址直接就是 stackauth.com 是 StackOverFlow 在谷歌 设置的自己的 redirect_url 后端地址,后面的参数有谷歌给予的授权码,就是下面 Location 中的 code
Status Code: 302 Found
Location: https://stackauth.com/auth/oauth2/google
  ?state=
  {"sid":1,"st":"59:3:1b8,16:c4729f2f7e47e8e0,10:1700192426,16:9b919914a5835436,ab53156abc79d1c3efbfbd96539ee08ce612452f12f2862ff35bb6c82ad2f805","cid":"717762328687-iludtf96g1hinl76e4lc1b9a82g457nn.apps.googleusercontent.com","k":"Google","ses":"272ab7f4f4cd4640b68720f3c05770f5"}
  &code=4/0AfJohXkprUYlXEgDK2tLi_a0hVMLckl6WnTepFNvwSbs0KT2je0WxaomUWbLPeDvfZIXQQ
  &scope=email profile https://www.googleapis.com/auth/userinfo.profile openid https://www.googleapis.com/auth/userinfo.email&authuser=0&prompt=none

2、浏览器收到上面的重定向后,就会用 Location 里的 url 再发出一次请求。这样就会带上授权码请求到 stackOverFlow 后端,然后 stackOverFlow 后端 会把授权码 code 和自己持有的 clientsecret 一起发给谷歌换取令牌

https://stackauth.com/auth/oauth2/google?
  state=
  {
"sid":1,"st":"59:3:1b8,16:c4729f2f7e47e8e0,10:1700192426,16:9b919914a5835436,ab53156abc79d1c3efbfbd96539ee08ce612452f12f2862ff35bb6c82ad2f805","cid":"717762328687-iludtf96g1hinl76e4lc1b9a82g457nn.apps.googleusercontent.com","k":"Google","ses":"272ab7f4f4cd4640b68720f3c05770f5"}   &code=4/0AfJohXkprUYlXEgDK2tLi_a0hVMLckl6WnTepFNvwSbs0KT2je0WxaomUWbLPeDvfZIXQQ   &scope=email profile https://www.googleapis.com/auth/userinfo.profile openid https://www.googleapis.com/auth/userinfo.email&authuser=0   &prompt=none

stackOverFlow 后台的响应,可以看到也是一个重定向 302。

Status Code: 302 Found
Location: https://stackoverflow.com/users/oauth/google?
  code=4/0AfJohXkprUYlXEgDK2tLi_a0hVMLckl6WnTepFNvwSbs0KT2je0WxaomUWbLPeDvfZIXQQ
  &state=
  {"sid":1,"st":"59:3:1b8,16:c4729f2f7e47e8e0,10:1700192426,16:9b919914a5835436,ab53156abc79d1c3efbfbd96539ee08ce612452f12f2862ff35bb6c82ad2f805","cid":"717762328687-iludtf96g1hinl76e4lc1b9a82g457nn.apps.googleusercontent.com","k":"Google","ses":"272ab7f4f4cd4640b68720f3c05770f5"}
  &s=272ab7f4f4cd4640b68720f3c05770f5

3、xx

https://stackoverflow.com/users/oauth/google?
  code=4/0AfJohXkprUYlXEgDK2tLi_a0hVMLckl6WnTepFNvwSbs0KT2je0WxaomUWbLPeDvfZIXQQ
  &state=
  {"sid":1,"st":"59:3:1b8,16:c4729f2f7e47e8e0,10:1700192426,16:9b919914a5835436,ab53156abc79d1c3efbfbd96539ee08ce612452f12f2862ff35bb6c82ad2f805","cid":"717762328687-iludtf96g1hinl76e4lc1b9a82g457nn.apps.googleusercontent.com","k":"Google","ses":"272ab7f4f4cd4640b68720f3c05770f5"}
  &s=272ab7f4f4cd4640b68720f3c05770f5

xx

Status Code: 302 Found
Location: https://stackoverflow.com/

到这里

 

后续的获取访问令牌,和通过访问令牌获取谷歌资源都是 StackOverflow 后端与谷歌进行交互的