1. 简介
OAuth 2.0是一个授权的标准,它允许第三方应用在用户授权后,访问用户在某网站上存储的数据(如用户信息、照片、联系人列表)。
它有基本的模型,也有几种变种,下边分别来看看。
2. 基本模型
2.1 角色
- Resource owner:资源拥有者,也就是用户
- Client:第三方的应用,想要访问你在另一网站的数据
- Resource Server:资源服务器,网站的业务服务
- Authorization Server:鉴权中心,与资源服务属于一个厂商
2.2 流程
基本流程如下:
(1)用户打开客户端以后,客户端要求用户给予授权。
(2)用户同意给予客户端授权。
(3)客户端使用上一步获得的授权,向认证服务器申请令牌。
(4)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。
(5)客户端使用令牌,向资源服务器申请获取资源。
(6)资源服务器确认令牌无误,同意向客户端开放资源。
文章介绍,使用前,Application(Client)可以先向Authorization Server注册,包括ApplicationName、回调URL等。其实将回调URL直接当query传递给Authorization Server就能完成功能,但这样做便于Authorization Server去管理三方的应用。
2.3 变体
- Authorization Code:授权码模式,要求client有客户端、有服务器,使用最多的
- Implicit:隐含模式,client有客户端即可完成
- Resource Owner password:密码模式,账号密码都交代给第三方的模式,简单了解即可
- Client Credentials:客户端证书,第三方是自己方的情况,简单了解即可
- Device code,最晚出现的一种,对设备进行授权,简单了解即可
注:这些变体是对基本模型中的1-4步进行了变化,5-6步都是相同
3. Authorization Code:授权码模式
网上能找到的图一般是这个图:
它是从OAuth标准来的,这里为了详细阐述流程,用时序图来看:
Client拿到AccessToken之后,就可以访问ResourceServer的资源了。
这里有2个流程:
- client获取到Authorization Code,这个在标准里一般被称为"Authorization Code flow"
- client再次获取到AccessToken,这个在标准里被称为"Implicit flow"
这里不禁要问,有了authorization code之后,为什么还需要access token?
stackoverflow给出了回答,这里简单概括一下:
主要是因为安全原因,OAuth2.0 试图满足这两条标准:
- 希望允许开发人员使用非 HTTPS 重定向 URI,因为并非所有开发人员都拥有启用 SSL 的服务器;
- 不希望黑客能够通过拦截请求来窃取访问/刷新令牌;
在"Implicit flow"中,access token是以二进制帧的方式传输,而不是"Authorization Code flow"中以URL参数的方式,也就不容易被拦截与攻击了。
4. Implicit:隐式模式
这种模式access token立即返回,而不需要Authorization code。它不需要第三方应用服务器参与,直接在浏览器中完成。
整个流程如下:
具体步骤如下:
(A)客户端将用户导向认证服务器。
(B)用户决定是否给于客户端授权。
(C)假设用户给予授权,认证服务器将用户导向客户端指定的"重定向URI",并在URI的Hash部分包含了访问令牌。
(D)浏览器向资源服务器发出请求,其中不包括上一步收到的Hash值。
(E)资源服务器返回一个网页,其中包含的代码可以获取Hash值中的令牌。
(F)浏览器执行上一步获得的脚本,提取出令牌。
(G)浏览器将令牌发给客户端。
与Authorization Code相比,有2点差异:
- Authorization server返回的是经过Hash的Access Token,再经过脚本才能提取AccessToken
- D、E两步是在浏览器上完成,而不是在client
有人说是简化模式,从步骤上看,并没有觉得简化
5. Resource Owner password:密码模式
这种模式,用户将网站的账号、密码直接给了client,client拿着去申请accesss token。这种情况,需要用户对client很信任,如谷歌浏览器,存储了很多账号密码一般。
(A)用户向客户端提供用户名和密码。
(B)客户端将用户名和密码发给认证服务器,向后者请求令牌。
(C)认证服务器确认无误后,向客户端提供访问令牌。
6. Client Credentials:客户端证书模式
这种没用户什么事啦,client直接申请Access Token。我觉得这种client与Authorization Server应该是一家的,不能称为第三方了。
(A)客户端向认证服务器进行身份认证,并要求一个访问令牌。
(B)认证服务器确认无误后,向客户端提供访问令牌。
7. Device Code:设备码模式
这种模式比以上几种出现的晚,是在rfc8628(2019年)中出现,以上4种是在rfc6749(2012年)。国内的资料中很少提及,这里就简单说一下。
这种模式针对的是设备,它们没有浏览器,只有有限的输入能力,例如用户在电视(没有键盘)上登录视频流应用程序(优酷、腾讯视频等)。
流程如下:

(A)设备向Authorization Server请求访问,并在请求中包含设备的标识符(Client Identifier)
(B)Authorization Server返回Device Code、User Code和一个验证URL
(C)设备将UserCode、验证URL给用户,并指示让他在浏览器上继续操作
(D)用户要在浏览器上访问验证URL,Authorization Server先对用户进行身份认证,然后提示用户输入user code,并想向用户询问,是否授权
(E)设备这时候通过Device Code、Client Identifier轮询Authorization Server是否完成授权
(F)Authorization Server给设备发放Access Token
8. 参考