OAuth 2.0 工作流程 授权模式 快速理解
OAuth 2.0 是一个行业的标准授权协议。OAuth 2.0 专注于简化客户端开发人员,同时为 Web 应用程序,桌面应用程序,手机和客厅设备提供特定的授权流程。
它的最终目的是为第三方应用颁发一个有时效性的令牌 token。使得第三方应用能够通过该令牌获取相关的资源。常见的场景就是:第三方登录。当你想要登录某个论坛,但没有账号,而这个论坛接入了如 Github、Google等登录功能,在你使用 Github 登录的过程中就使用的 OAuth 2.0 协议。
角色
首先需要介绍的是 OAuth 2.0 协议中的一些角色,整个授权协议的流程都将围绕着这些角色:
resource owner
,资源所有者,能够允许访问受保护资源的实体。一般指你自己。resource server
,资源服务器,托管受保护资源的服务器。 指你需要访问的资源服务器。client
,资源所有者使用的客户端 如:web网站,移动应用等。authorization server
,授权服务器,能够向客户端颁发令牌。user-agent
,用户代理,帮助资源所有者与客户端沟通的工具
工作流程
A: 向资源服务器发起认证请求
B:资源服务器返回认证成功,一般会返回一个code标识
C:带上认证过的code向授权服务器发起请求,换取访问令牌
D:授权服务器返回访问令牌 ACCESS_TOKEN
E:客户端带上访问令牌访问在资源服务器中受保护的资源
我们以微信网页授权举例:
1 第一步:用户点击一串微信指定的url,打开微信网页,弹出授权提示,点击同意授权,获取code,携带code重定向到开发者服务器
2 第二步:在后端完成,通过code换取网页授权access_token
3 第三步:如果access_token过期了,刷新access_token(如果需要)
4 第四步:携带有效 access_token 向微信资源服务器,拉取用户信息(需scope为 snsapi_userinfo)
令牌与密码
令牌(token)与密码(password)的作用是一样的,都可以进入系统,但是有三点差异。
(1)令牌是短期的,到期会自动失效,用户自己无法修改。密码一般长期有效,用户不修改,就不会发生变化。
(2)令牌可以被数据所有者撤销,会立即失效。以上例而言,屋主可以随时取消快递员的令牌。密码一般不允许被他人撤销。
(3)令牌有权限范围(scope),比如只能进小区的二号门。对于网络服务来说,只读令牌就比读写令牌更安全。密码一般是完整权限。
上面这些设计,保证了令牌既可以让第三方应用获得权限,同时又随时可控,不会危及系统安全。这就是 OAuth 2.0 的优点。
注意,只要知道了令牌,就能进入系统。系统一般不会再次确认身份,所以令牌必须保密,泄漏令牌与泄漏密码的后果是一样的。 这也是为什么令牌的有效期,一般都设置得很短的原因。s
四种授权模式
OAuth 2.0 规定了四种获得令牌的流程。你可以选择最适合自己的那一种,向第三方应用颁发令牌。每一种方式都是解决了特定场景下问题,具体可以查看模式下的应用场景。
注意,不管哪一种授权方式,第三方应用申请令牌之前,都必须先到系统备案,说明自己的身份,然后会拿到两个身份识别码:客户端 ID(client ID)和客户端密钥(client secret)。这是为了防止令牌被滥用,没有备案过的第三方应用,是不会拿到令牌的。
备案,是指在访问资源哪一方的系统上需要先注册开放平台账号,然后申请应用,会得到一个key和一个secret。
为了通俗的解释,我们假设:
C为开发者客户端 S为开发者服务器 S1为认证服务器 S2为受保护的资源服务器
授权码模式(authorization code)
最安全,最常用,推荐
工作流程
C通过一个url 携带上已经备案好的clientId(微信叫AppId)访问S1服务器上的资源
S1服务器经过对clientId进行校验合法,返回一个授权码code
紧接着这个url会带上code,重定向到S服务器
S服务器通过在后端携带code向S1发起API请求,获取access_token
S服务器携带access_token可以访问S2服务器上受保护的资源,如获取用户信息,特殊接口
应用场景
第三方网页授权,第三方网页登陆
如:登陆豆瓣,可以用QQ登陆
特点:web应用,针对需要授权本系统用户权限去登陆其他服务器
密码模式(resource owner password credentials)
工作流程
如果你高度信任需要授权的服务器,可以直接带上账号密码去S1服务器获取认证,
S1服务器会立即响应access_token,这里不需要任何跳转。
应用场景
适合高度信任的应用,一般是内部服务之间使用
如 公司C 由两个 App A和B
访问A需要B的授权,因为用户隶属一个公司下,没必要再去搞一个新的账号密码,直接利用B应用的注册账号,授权给A,内部之间服务信任,方便快捷。
隐藏模式(implicit)
允许直接向前端颁发令牌。这种方式没有授权码这个中间步骤
工作流程
前端携带clientId直接跳转到S1服务器
S1服务器重定向到S服务器,直接在url的锚点上带上access_token,而不是查询字符串上,如 https://s.com/result#token=ACCESS_TOKEN
浏览器跳转时,锚点不会发到服务器,就减少了泄漏令牌的风险
应用场景
纯前端应用,没有服务器的交互
这种方式把令牌直接传给前端,是很不安全的。因此,只能用于一些安全要求不高的场景,并且令牌的有效期必须非常短,通常就是会话期间(session)有效,浏览器关掉,令牌就失效了。
客户端凭证模式(client credentials)
工作流程
直接根据clientId和secret即可获取access_token,无需用户参与,是服务端的行为
通过S服务器直接向S1服务器发起请求,获取access_token,没有用户参与。
应用场景
服务之间调用授权服务
适合多个后端业务模块之间的信任认证授权
微服务模块很多个,在跨云跨数据中心,使用外网调用的适合,需要做合法认证,可以使用此方式。