迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 网络 >

OAuth2.0 - 颁发访问令牌的方式

作者:迹忆客 最近更新:2021/08/17 浏览次数:

在上一篇文章全面了解OAuth2.0中我们介绍了OAuth2.0 是一种授权机制,主要的目的是为想要共享资源的网站或应用之间颁发令牌。在开始本篇文章之前,我们假定你已经了解了OAuth2.0 的含义和设计原理,否则的话还请先回去阅读全面了解OAuth2.0这篇文章。

本篇文章主要是讲解如何使用 客户端的凭据来获取访问令牌。这里我们首先来看一下客户端的凭据

客户端的凭据

当客户端是资源所有者时,或者当授权范围仅限于客户端控制下的受保护资源时,客户端凭据可用作授权许可。客户端凭据授权流程用于获取访问令牌以授权 API 请求。

使用客户端凭据授权,获取的访问令牌仅授予客户端应用程序搜索和获取目录文档的权限。

下面我们简单描述一下客户端凭据授权流程

第一、客户端向授权服务器进行身份验证,并从令牌端点发出访问令牌请求。

OAuth2.0-客户端凭据-请求访问令牌

第二、授权服务器对客户端进行身份验证,如果客户端提供的身份信息有效且经过授权,则提供访问令牌。

OAuth2.0-服务端验证提供访问令牌

在客户端凭据这里,涉及到几个知识点。为了不占用太多的篇幅,所以将这几个知识点单独放在一篇文章中。在继续下面的内容之前,建议先看一下 OAuth2.0 客户端凭据扩展知识点 这篇文章,了解一下这几个知识点。

这里我们说一下这个客户端的凭据的获得。一般情况下,客户端的凭据包括认证服务颁发给客户端的 客户端ID客户端密钥。开发者需要去认证服务后台进行申请,同时需要填写一个回调地址,回调地址的作用就是当用户登录成功之后跳转的一个地址。同时会在该地址后面带上一个参数——授权码。用户可以将 授权码、客户端ID和客户端密钥发送给认证服务从而可以换取访问令牌。详细获取访问令牌的方式我们接下来会讲。这里需要知道的就是客户端的凭据如何获取。

例如我们将要接入的微博平台,需要在其后台进行申请,然后它会颁发给我们客户端的凭据

应用申请

应用信息

其中 App Key 和 App Secret 就是对应的 客户端 ID 和 客户端密钥。 在接下来获取访问令牌的流程中,我们不再介绍客户端凭据的获取方式。直接假定已经获取了客户端凭据,所有的都是这之后的流程。

获取访问令牌

访问令牌是一个标识用户、应用程序或页面的字符串。访问令牌包括很多信息。例如令牌到期时间,哪个应用程序创建了该令牌等。

获取访问令牌的整体流程如下:

  • 首先,需要从 API 控制台/认证服务后台 申请 OAuth 2.0 客户端凭据。
  • 然后,客户端从授权服务器请求访问令牌。
  • 客户端从响应中提取访问令牌并将令牌发送到希望访问的 API,进行数据通信。

下面是一个假的请求例子

https://api.example.com/oauth2/authorize?client_id=your_client_id&redirect_uri=your_url 
   &response_type=code

OAuth 2.0 规定了四种获得令牌的流程。分别为

  • 授权码(authorization-code)
  • 隐藏式(implicit)
  • 密码式(password):
  • 客户端凭证(client credentials)

其中,授权码方式用的比较广泛,而且相对来说最安全。下面我们分别来介绍这几种方式。

授权码

授权码方式是使用最为广泛的,并且安全性相对来说也比较高。但是其流程相对于其他几种方式较为复杂。下面我们来看一下其整个获取访问令牌的过程。

OAuth2.0授权码获取访问令牌流程

下面我们来分解一下这个图

、用户通过使用客户端应用访问资源所有者的资源。然后被客户端应用重定向到认证服务的授权登录界面。

、用户通过提供自己在资源服务的账号和密码获取表示同意授权,从而在认证服务端获取授权码。

OAut2.0 请求授权码

、认证服务将用户重定向到该客户端应用程序注册的回调URI,并且带着参数授权码。

OAuth2.0 返回授权码

、客户端应用程序提取授权码,并且将客户端ID、客户端密钥和刚获取的授权码发送给认证服务,从而获取访问令牌。

https://api.example.com/oauth/token?
 client_id=CLIENT_ID&
 client_secret=CLIENT_SECRET&
 grant_type=authorization_code&
 code=AUTHORIZATION_CODE&
 redirect_uri=CALLBACK_URL

client_id 和 client_secret 是用来确认客户端应用程序是否是合法的注册的应用。grant_type参数的值是AUTHORIZATION_CODE,表示采用的授权方式是授权码,code参数是上一步拿到的授权码。redirect_uri参数是令牌颁发后的回调网址。

OAuth2.0 请求访问令牌

、认证服务收到请求以后,就会颁发令牌。返回一段JSON数据:

{    
  "access_token":"ACCESS_TOKEN",
  "token_type":"bearer",
  "expires_in":2592000,
  "refresh_token":"REFRESH_TOKEN"
}

上面 JSON 数据中,access_token字段就是我们需要的访问令牌。其中还包括 expires_in(访问令牌的过期时间),refresh_token(刷新令牌)用来刷新访问令牌的

OAuth2.0 返回访问令牌

隐藏式

对于这种方式的应用场景就是有些Web应用是纯前端的,并没有后端可以存储访问令牌。这时我们就不能用上面说的授权码的方式了。因为我们必须将访问令牌存储在前端。因为没有授权码中间步骤,所以称为 隐藏式

、用户通过使用客户端应用访问资源所有者的资源。然后被客户端应用重定向到认证服务的授权登录界面。此时的地址如下

https://api.example.com/oauth/authorize?
  response_type=token&
  client_id=CLIENT_ID&
  redirect_uri=CALLBACK_URL&
  scope=read

response_type参数为token,表示要求直接返回令牌。

、用户在认证服务的登录页面登录后同意给予客户端应用程序网站授权。这时,认证服务就会跳回redirect_uri参数指定的跳转网址,并且把令牌作为 URL 参数,传给 A 网站。

https://jiyik.com/callback#token=ACCESS_TOKEN

上面 URL 中,token参数就是令牌,因此客户端应用可以直接在前端拿到访问令牌。

OAuth2.0 隐藏式 请求访问令牌

这种方式把令牌直接传给前端,是很不安全的。因此,只能用于一些安全要求不高的场景,并且令牌的有效期必须非常短。

密码式

此种方式就是用户直接将自己在资源服务的用户名和密码告诉客户端应用。当然此种方式要基于用户绝对信任该客户端应用。

客户端应用直接拿着用户的账号和密码去认证服务换取访问令牌。

https://api.example.com/token?
  grant_type=password&
  username=USERNAME&
  password=PASSWORD&
  client_id=CLIENT_ID

上面 URL 中,grant_type参数是授权方式,这里的password表示"密码式",username和password是用户的用户名和密码。

然后,认证服务验证身份通过后,直接给出令牌。注意,这时不需要跳转,而是把令牌放在 JSON 数据里面,作为 HTTP 回应。

凭证式

此种方式适用于没有前端的场景。例如 命令行应用。

首先,命令行应用通过 curl 向认证服务发送如下请求

https://api.example.com/token?
  grant_type=client_credentials&
  client_id=CLIENT_ID&
  client_secret=CLIENT_SECRET

grant_type=client_credentials表示采用凭证式,client_id和client_secret是认证服务颁发给客户端应用的客户端凭据。可以以此来判断客户端应用的合法性。

接着,认证服务验证通过后,直接返回访问令牌。

以上几种方式可以帮助我们获取到访问令牌。拿到访问令牌之后,客户端应用程序就可以使用访问令牌和资源服务进行通信了。

为了安全,每一个访问令牌都有一个有效期,也就是我们在上面提到的字段expires_in。这个字段是表示访问令牌的有效时长。访问令牌的有效期到了,如果我们再使得用户走一遍上述的授权流程去获取访问令牌那对于用户来说是很痛苦的一件事情。

像我们项目中和各个电商平台对接的时候,访问令牌都有一个过期时间。在将要过期之前,我们都是通过平台提供的refresh_token来自动获取新的访问令牌。这对于用户来说是透明的,他不需要关心访问令牌过期的问题。

https://api.example.com/oauth/token?
  grant_type=refresh_token&
  client_id=CLIENT_ID&
  client_secret=CLIENT_SECRET&
  refresh_token=REFRESH_TOKEN

OAuth2.0 刷新令牌使用过程

除非注明转载,本站文章均为原创或翻译,欢迎转载,转载请以链接形式注明出处

本文地址:

迹忆客

专注技术分享,项目实战分享!

技术宅 乐于分享 7年编程经验
社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

热门文章

教程更新

热门标签