【译文】OAuth 2 介绍

原文:An Introduction to OAuth 2

简介

OAuth 2 是一个授权框架,可以让应用获取一个 HTTP 服务(如 Facebook, GitHub, DigitalOcean)的用户账户的有限的访问。原理是通过持有用户账户的服务主机验证用户身份后授权第三方应用访问用户账户。OAuth 2 为 web 和桌面应用、移动设备提供授权工作流程。

这篇信息指南针对应用程序开发人员,简要说明了 OAuth 2 里的角色分类、授权类型、用例和工作流程。

从 OAuth 角色分类开始讲起。

OAuth 角色分类

OAuth 定义了4种角色:

  • 资源所有者
  • 客户端
  • 资源服务器
  • 授权服务器

接下来我们将详细描述这几个角色。

资源所有者:用户

资源所有者是授权一个应用使用他们账户的用户。应用使用用户账户受限于授予的权限范围(如:读或写权限)。

资源/授权服务器:API

资源服务器持有受保护的用户账户,由它来验证用户身份然后将访问口令传给应用。

以应用开发者的角度来看,一个服务的 API 既是资源服务器也是授权服务器。我们将这两个角色结合成服务方角色或 API 角色。

客户端:应用

客户端就是想要使用用户账户的应用。在这之前,需要经过用户授权,而授权的验证由 API 来做。

抽象协议工作流程

现在你对 OAuth 角色分类有了一些了解,接着通过一个图来看他们是如何协作的:


抽象协议工作流程图

该图详细解释:
1、应用请求用户授权访问服务方资源。
2、如果用户授权了,应用收到授权许可。
3、应用提供可以证实自己的身份证明和授权许可向授权服务器(API)请求访问口令(access token)。
4、如果应用的身份证明和授权许可都通过了验证,授权服务器(API)发送一个访问口令给应用,授权完成。
5、应用提供访问口令从资源服务器(API)请求资源。
6、如果访问口令有效,资源服务器(API)提供资源给应用。

实际流程因授权类型不同会有不同,这是总体的思路。之后我们将探索不同的授权类型。

应用注册

在应用使用 OAuth 之前你必须在这个服务上注册你的应用。这需要通过在服务网站上填写一个『开发者』或『API』注册表单,表单需要提供以下信息(可能还有应用详细信息):

  • 应用名字
  • 应用网站
  • 重定向 URI 或回调 URL

重定向 URI 是在用户授权(或拒绝授权)以后服务方要重定向的位置,也就是你的应用处理授权码或访问口令的地方。

客户端 ID 和客户端密钥

在你的应用注册后服务方会给你一个以客户端标志符(ID)和客户端密钥为代表的『客户端证书』。客户端 ID 是一个公开暴露的字符串,用于服务 API 标识这个应用,也用于生成授权相关的各种 URL。客户端密钥用于在应用请求访问用户账户时服务 API 鉴定应用身份,必须要保证在应用和 API 之间私有。

授权许可

在之前的抽象协议工作流程里,前四步获得授权许可和访问口令。授权许可类型依赖于应用请求授权所使用的方法和 API 支持的许可类型。OAuth 2 规定了4种批准类型,在不同的案例里使用不同的批准类型:

  • 授权码:用于服务器端应用。
  • 隐含:用于手机应用或网页应用(即运行于用户设备的应用)
  • 资源所有者密码验证:用于受信赖的应用,如服务方自己持有的应用。
  • 客户端验证:用于应用 API 访问。

接着我们要详细说下不同类型的用例和工作流程。

授权类型:授权码

授权码类型是最常用的类型,充分利用了服务器端应用代码不公开的优点,即客户端密钥可以保持私有。该模式是一种基于重定向的流程,这意味着应用必须可以和用户代理(如用户的浏览器)进行交互且要能收到用户代理转发的 API 授权码。

下面是授权码类型工作流程图:

授权码模式流程图

步骤1:授权码链接

首先用户得到一个像这样的授权码链接:

https://cloud.digitalocean.com/v1/oauth/authorize?
response_type=code&
client_id=CLIENT_ID&
redirect_uri=CALLBACK_URL&
scope=read

链接组成部分:

  • https://cloud.digitalocean.com/v1/oauth/authorize:授权 API 端点
  • response_type=code:表明应用正在请求授权码
  • client_id=CLIENT_ID:应用的客户端 ID(用于 API 辨认应用身份)
  • redirect_uri=CALLBACK_URL:服务方在授予授权码后将用户代理重定向的位置
  • scope=read:表明应用请求的权限范围

步骤2:用户授权给应用

当用户点击上面那个链接,如果没有登录的话首先应该登录到那个服务。然后服务方提示用户是否要授权给那个应用使用他们的账号。下图是一个授权提示:

授权提示图

上图是 DigitalOcean 的授权页面截图,可以看到『Thedropletbook』应用正在请求『manicas@digitalocean.com』账号的『读』权限。

步骤3:应用收到授权码

如果用户点击『授权给应用』,服务方将用户代理重定向到应用之前提供的重定向 URI,这时 URI 带有授权码。重定向的网址看起来像这样(假设应用网址是"dropletbook.com"):

https://dropletbook.com/callback?code=AUTHORIZATION_CODE

步骤4:应用请求访问口令

应用使用授权码和客户端密钥向 API 请求访问口令。下面是一个 POST 请求口令的例子:

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

步骤5:应用收到访问口令

如果验证通过,API 将返回一个包含访问口令的响应(和一个可选的更新口令)。完整的响应看起来像这样:

{
  "access_token":"ACCESS_TOKEN",
  "token_type":"bearer",
  "expires_in":2592000,
  "refresh_token":"REFRESH_TOKEN",
  "scope":"read",
  "uid":100101,
  "info":{
    "name":"Mark E. Mark",
    "email":"mark@thefunkybunch.com"
  }
}

现在应用已经获得了授权!接下来可能使用访问口令来访问用户的账号,当然访问受所授的权限限制,直到口令到期或被取消授权。如果有收到更新口令(refresh token),可以在当前口令过期后用它来请求新的口令。

授权类型:隐式

隐式授权类型用于手机应用或 web 应用(也就是运行在 web 浏览器的应用),这类应用的客户端密钥私密性没有保障。隐式授权类型同样是基于重定向的工作流程,只是访问口令是给用户代理也就是应用的,所以访问口令可能暴露给用户和用户设备上的其它应用。同时,这个流程不需要验证应用身份,只要有重定向的 URI(在服务方那边注册了的)就可以提供这个服务了。

隐式授权类型不支持更新口令。

隐式授权类型基本工作流程如下:应用要求用户授权,然后授权服务器传回访问口令给用户代理,用户代理将其传递给应用。下图是详细点的过程图:

隐式授权流程图

步骤1:隐式授权链接

在隐式授权类型里,一个向 API 请求口令的授权链接代表了用户。这个链接就像是授权码链接,只是它是请求一个口令而不是授权码(注意响应类型是口令):

https://cloud.digitalocean.com/v1/oauth/authorize?
response_type=token&
client_id=CLIENT_ID&
redirect_uri=CALLBACK_URL&
scope=read

步骤2:用户授权给应用

当用户点击上面那个链接,需要先登录到服务方来验证用户的身份。然后用户将看到服务方提示是否授权给应用。提示就像之前说过的那样。

步骤3:用户代理重定向到带有访问口令的指定网址

如果用户点击了『授权』,服务方将用户代理重定向到应用提供的重定向地址,重定向时包含访问口令。它看起来像这样:

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

步骤4:用户代理遵循重定向 URI

用户代理保持带有访问口令的 URI。

步骤5:应用发送提取访问口令脚本

应用返回一个带有可以从整个重定向 URI 里提取口令的脚本的网页。

步骤6:访问口令传给应用

用户代理执行给出的脚本然后把访问口令传递给应用。

现在应用已经获得了授权!接下来可能使用访问口令来访问用户的账号,当然访问受所授的权限限制,直到口令到期或被取消授权。

授权类型:资源持有者密码验证

在这个类型里,用户直接提供他们在服务方那边的凭证(用户名和密码)给应用,用这些凭证可以从服务方那边获得访问口令。这种授权类型只有在别的授权类型不可行的时候用于授权服务器上。或者只有在应用可信的情况下使用(如服务方持有的应用或用户操作系统应用)。

密码验证流程

在用户提供凭证给应用后应用将向授权服务器请求访问口令。POST 请求看起来像这样:

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

如果用户凭证通过验证,授权服务器返回访问口令给应用。现在应用已被授权!

注意:DigitalOcean 目前不支持这种授权,所以上面的链接指向虚构的授权服务器『oauth.example.com』。

授权类型:客户端验证

这种授权类型给应用提供了一种让应用自己管理服务账号的方式。使用场景是应用想要更新其注册的描述或重定向的 URI,又或者通过 API 访问其它存储于服务账号上的数据。

客户端验证流程

应用通过发送凭证(应用的客户端 ID 和客户端密钥)给授权服务器请求访问口令。POST 请求看起来像这样:

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

如果凭证通过了验证,授权服务器返回访问口令给应用。

访问口令使用用例

应用有了访问口令以后可能通过 API 访问可访问的用户账户信息。

一下是一个使用 curl 的 API 请求例子(注意这里包含了访问口令):

curl -X POST -H "Authorization: Bearer ACCESS_TOKEN""https://api.digitalocean.com/v2/$OBJECT"

假设访问口令有效,将以 API 文档里写的那样执行这个 API。如果访问口令没有通过验证,将返回一个『invalid_request』错误。

更新口令流程

在一个访问口令过期后,再使用它来访问 API 将收到『Incalid Token Error』。在这一点上,如果一开始获取访问口令的时候同时也返回了更新口令,更新口令可以用于请求一个新的访问口令。

以下是一个使用了更新口令的 POST 请求新访问口令例子:

https://cloud.digitalocean.com/v1/oauth/token?grant_type=refresh_token&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&refresh_token=REFRESH_TOKEN

结论

现在你应该对 OAuth 2 如何工作有了很好的了解,知道何时改使用何种授权流程。

如果想学习更多关于 OAuth 2 的知识,可以看看下面这几篇文:
How To Use OAuth Authentication with DigitalOcean as a User or Developer
How To Use the DigitalOcean API v2
The OAuth 2.0 Authorization Framwork

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,591评论 18 139
  • 本文以一种简化的格式描述OAuth 2.0 ,以帮助开发人员和服务提供者实现该协议。 The OAuth 2 sp...
    KennethChen93阅读 4,137评论 1 11
  • 本文希望以应用场景的角度出发,帮助大家快随了解OAuth协议流程,更为清楚明白的介绍在各种情况使用什么授权模式更为...
    登高且赋阅读 30,541评论 1 40
  • 今年年初,第一份实习,接触了如何使用Facebook API, Twitter API...去获取数据,自动发个F...
    Jason_Yuan阅读 16,072评论 3 51
  • 难得今天清闲,带俩孩子到妹妹家串个门。 一直玩到5点,该回家了 ,伴随着凉凉的细雨,我和女儿骑着自行车在人行道上狂...
    吕玥妈咪阅读 131评论 0 3