coverPiccoverPic

关于 OAuth 2.0 的笔记

前言

OAuth 2.0 是目前最流行的授权机制,用来授权第三方应用,获取用户数据。现在 OAuth 一般指 OAuth 2.0,流程中,主要有如下四个角色:

  1. Resource Owner: 用户拥有资源服务器上面的数据。例如我有一个 Github 账号,我有我的用户信息的数据,通俗来说就是使用 OAuth 登录的用户。
  2. Resource Server: 资源服务器,存储用户信息的 API Service
  3. Client: 客户端,想要访问用户的客户端,例如前端网页,比如这个博客就支持 Github 的 OAuth 登录。
  4. Authorization Server: 授权服务器,获取访问 Resource Server 的 token。这里的 token 一般是 JWT 形式的 access_token,也可以支持 refresh_token,看具体实现。

客户端开发者一般会在授权服务器注册客户端对应的 OAuth 应用,从而获得应用的 id:client_id,和应用访问授权服务器的密钥 client_secret。

授权流程

OAuth 2.0 一般有 4 种模式:授权码式(也是用得最多的)、隐藏式、密码式、凭证式。

授权码式

授权码式(authorization code)常见于拥有前端和后端的应用,前端从授权服务器获取授权码,再由应用的后端获取访问资源服务器的 token。用户使用带有client_idredirect_uriscope的 URL 访问授权服务器。client_id应用是在授权服务器上注册的 OAuth 应用的 id,redirect_uri是获取了授权码后,返回客户端的链接,通常会带有code的 query 参数记录授权码。scope表示访问资源服务器的权限。其实也不一定是这 3 个字段,看具体实现而定。

例如:在这个博客使用 Github 登录,浏览器会跳转到 https://github.com/login?client_id=xxxxx ,用户在 Github 登录然后授权了之后,会跳转到这个博客的 https://deerblog.gu-nami.com/github?code=yyyyyy ,在这个页面,会把code参数传给后端服务器获取访问 Github 信息的 token。然后然后,后端服务器会根据 Github 上面的信息找到对应的博客用户,完成登录。

为什么要用授权码换 access_token?主要是因为在 URL 上面记录 access_token,浏览器等地方可能会记录访问记录,把 URL 的 access_token 也记录下来,在过期时间内,看到用户电脑的人都可以直接用 URL 的 access_token 访问资源服务器可能引起安全问题。

sequenceDiagram
Resource Owner->>Client:进行 OAuth 登录
Client->>Authorization Server:https://test/authorize?
response_type=code&
client_id=CLIENT_ID&
redirect_uri=CALLBACK_URL&
scope=read Resource Owner->>Authorization Server:进行授权 Authorization Server->>Client:https://CALLBACK_URL?code=CODE note right of Client: 后端服务器发起 Client->>Authorization Server:client_secret、code Authorization Server->>Client:access_token[、refresh_token] note right of Client: 访问资源服务器 Client->>Resource Server:access_token Resource Server->>Client:对应的资源

隐藏式

隐藏式即 implicit,适用于没有后端服务器的应用,直接由授权服务器返回 access_token:

sequenceDiagram
Resource Owner->>Client:进行 OAuth 登录
Client->>Authorization Server:https://test/authorize?
response_type=implicit&
client_id=CLIENT_ID&
redirect_uri=CALLBACK_URL&
scope=read Resource Owner->>Authorization Server:进行授权 Authorization Server->>Client:https://CALLBACK_URL?access_token=ACCESS_TOKEN note right of Client: 访问资源服务器 Client->>Resource Server:access_token Resource Server->>Client:对应的资源

密码式

密码式即 password,适用于高度信任的应用之间的授权,例如企业内部系统之间。用户直接在客户端输入授权服务器的账号密码进行登录获取 access_token:

sequenceDiagram
Resource Owner->>Client:进行 OAuth 登录,输入账号密码
Client->>Authorization Server:账号密码
Authorization Server->>Client:access_token
note right of Client: 访问资源服务器
Client->>Resource Server:access_token
Resource Server->>Client:对应的资源

凭证式

凭证式,即 client credentials,通过后端服务器或者命令行直接访问资源,无需前端界面:

sequenceDiagram
Resource Owner->>Client:进行 OAuth 登录
Client->>Authorization Server:https://test/authorize?
response_type=credentials&
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET&
redirect_uri=CALLBACK_URL&
scope=read Authorization Server->>Client:access_token note right of Client: 访问资源服务器 Client->>Resource Server:access_token Resource Server->>Client:对应的资源

OpenID Connect

OpenID Connect 是在OAuth 2.0 协议基础上增加了身份验证层 (Identity Layer)。OAuth 2.0 定义了通过 access_token 去获取请求资源的机制,但是没有定义提供用户身份信息的标准方法。OpenID Connect 作为 OAuth 2.0 的扩展,实现了身份认证(Authentication)的流程。

OpenID Connection 在 OAuth2.0 的基础上额外增加了 UserInfo 的 Endpoint,也就是获取用户信息的 API。OpenID Connect 根据用户的 id_token 来验证用户,并获取用户的基本信息。

id_token 通常也是JWT,可以和 access_token 一起返回给客户端(看具体实现,有直接拿 access_token 当 id_token 用的)。

0 条评论未登录用户
Ctrl or + Enter 评论
🌸 Run