因为工作的原因,需要提供一个根据用户代码仓库构建现代化应用的能力。当用户提交了代码,将自动拉取代码并触发构建部署的工作流。上诉场景让我接触到 OAuth App 的概念。

下文主要是针对 Oauth2.0 做一个介绍。

什么是 OAuth

OAuth官方的简介是:

An open protocol to allow secure API authorization in a simple andstandard method from web, mobile and desktop applications.

随着大量开放平台的出现,建立在开放平台之上的各种第三方应用也在大量冒出,出于对安全性和统一标准的要求,于是出现了 OAuth 协议

简单来说,OAuth 是一种开放的协议,他能为桌面程序或者基于 BSweb 应用提供一种简单的标准方式去访问需要用户授权的 API(ApplicationProgramming Interface)服务,而且任何第三方都可以使用 OAuth 认证服务。在为第三方提供服务的过程中,他还能起到保护用户账号安全的作用。

OAuth 2.0

20104 月发布了 OAuth2.0,是 OAuth 协议的下一版本,但与 OAuth 1.0 版本互不兼容。

OAuth 2.0 是目前最流行的授权机制,用来授权第三方应用,获取用户数据。

在上面的给出 OAuth 的定义中其实就已经说明白了它的作用,但是这个标准比较抽象,使用了很多术语。这里以快递员的例子做一个介绍,OAuth2.0 到底是什么。

举例 – 快递员

我住在一个大型的居民小区。

小区有门禁系统。

进入的时候需要输入密码。

我经常网购和外卖,每天都有快递员来送货。我必须找到一个办法,让快递员通过门禁系统,进入小区。

如果我把自己的密码,告诉快递员,他就拥有了与我同样的权限,这样好像不太合适。万一我想取消他进入小区的权力,也很麻烦,我自己的密码也得跟着改了,还得通知其他的快递员。

有没有一种办法,让快递员能够自由进入小区,又不必知道小区居民的密码,而且他的唯一权限就是送货,其他需要密码的场合,他都没有权限?

OAuth

授权机制的设计

于是,我设计了一套授权机制。

第一步,门禁系统的密码输入器下面,增加一个按钮,叫做”获取授权”。快递员需要首先按这个按钮,去申请授权。

第二步,他按下按钮以后,屋主(也就是我)的手机就会跳出对话框:有人正在要求授权。系统还会显示该快递员的姓名、工号和所属的快递公司。

我确认请求属实,就点击按钮,告诉门禁系统,我同意给予他进入小区的授权。

第三步,门禁系统得到我的确认以后,向快递员显示一个进入小区的令牌(access token)。令牌就是类似密码的一串数字,只在短期内(比如七天)有效。

第四步,快递员向门禁系统输入令牌,进入小区。

有人可能会问,为什么不是远程为快递员开门,而要为他单独生成一个令牌?这是因为快递员可能每天都会来送货,第二天他还可以复用这个令牌。另外,有的小区有多重门禁,快递员可以使用同一个令牌通过它们。

互联网场景

我们把上面的例子搬到互联网,就是 OAuth 的设计了。

首先,居民小区就是代码托管平台,如 Github。当我通过外卖软件下另一个订单(提交代码),快递员想要把这个订单送到我手上(执行 CI/CD),就必须经过小区的的”门禁系统”(拿到我提供的令牌)。

其次,快递员就是第三方应用(提供 CI/CD 的能力),想要穿过门禁系统,进入小区。

最后,我就是用户本人,同意授权第三方应用进入小区,拉取我的代码。

简单说,OAuth 就是一种授权机制。数据的所有者告诉系统,同意授权第三方应用进入系统,获取这些数据。系统从而产生一个短期的进入令牌(access token),用来代替密码,供第三方应用使用。

令牌与密码

令牌(access token)与密码(password)的作用是一样的,都可以进入系统,但是有三点差异。

(1)令牌一般是短期的,到期会自动失效,用户自己无法修改。密码一般长期有效,用户不修改,就不会发生变化。

(2)令牌可以被数据所有者撤销,会立即失效。以上例而言,屋主可以随时取消快递员的令牌。密码一般不允许被他人撤销。

(3)令牌有权限范围(scope),比如只能进小区的二号门。对于网络服务来说,只读令牌就比读写令牌更安全。密码一般是完整权限。

上面这些设计,保证了令牌既可以让第三方应用获得权限,同时又随时可控,不会危及系统安全。这就是 OAuth 2.0 的优点。

注意,只要知道了令牌,就能进入系统。系统一般不会再次确认身份,所以令牌必须保密,泄漏令牌与泄漏密码的后果是一样的。 这也是为什么令牌的有效期,一般都设置得很短的原因。

一个简单的例子:https://github.com/heiemooa/heiemooa/tree/demos/demos/node-oauth-demo