什么是OAuth2.0
OAuth(Open Authorization)是一个关于授权(authorization)的开放网络标准,允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用或分享他们数据的所有内容。OAuth在全世界得到广泛应用,目前的版本是2.0版
用户可以通过选择其他登录方式来使用gitee,这里就使用到了第三方认证。
来自RFC 6749
OAuth 引入了一个授权层,用来分离两种不同的角色:客户端和资源所有者。......资源所有者同意以后,资源服务器可以向客户端颁发令牌。客户端通过令牌,去请求数据。
OAuth协议:https://tools.ietf.org/html/rfc6749
协议特点:
简单:不管是OAuth服务提供者还是应用开发者,都很易于理解与使用;
安全:没有涉及到用户密钥等信息,更安全更灵活;
开放:任何服务提供商都可以实现OAuth,任何软件开发商都可以使用OAuth;
应用场景
原生app授权:app登录请求后台接口,为了安全认证,所有请求都带token信息,如果登录验证、 请求后台数据。
前后端分离单页面应用:前后端分离框架,前端请求后台数据,需要进行oauth2安全认证
第三方应用授权登录,比如QQ,微博,微信的授权登录。
为什么要使用OAuth2.0
在OAuth之前,HTTP Basic Authentication, 即用户输入用户名,密码的形式进行验证, 这种形式是不安全的。OAuth的出现就是为了解决访问资源的安全性以及灵活性。OAuth使得第三方应用对资源的访问更加安全。
小静美女现在想要将手机云中的相册美照,放置到QQ空间中展示,按照传统方式小静要怎么做呢?
将照片从“手机云”中download下来,在上传到“QQ空间相册”展示。
下载/上传太麻烦了,小静可以直接把“云相册”的账号和密码告诉“QQ空间”,由“QQ空间”下载照片在上传。
对于上面的两种方法,方法一太麻烦但是相对于小静来说是安全的;方法二对于小静是比较方便,但是将账号密码告诉了“QQ空间”就相当于把所有的“手机云”资料交给了它,这肯定是不可取的。
所以,为了解决类似上面的问题,Oauth协议诞生了。
OAuth2.0协议流程
应用场景
原生app授权:app登录请求后台接口,为了安全认证,所有请求都带token信息,如果登录验证、 请求后台数据。
前后端分离单页面应用:前后端分离框架,前端请求后台数据,需要进行oauth2安全认证
第三方应用授权登录,比如QQ,微博,微信的授权登录。(本系列课程应用场景讲解)
步骤解读:
第1步:浏览器打开Gitee码云,点击微信方式授权登录,重定向到微信授权服务页面等待获取授权码;
第2步:用户打开手机登录微信扫描“二维码”,点击“允许”授权,将重定向到客户端(Gitee)应用提供的URI;
第3步:客户端(Gitee)使用上一步获取的授权码,向微信授权服务器申请令牌(Token);
第4步:微信授权服务器对客户端(Gitee)进行认证以后,确认无误,同意发放令牌;
第5步:客户端使用令牌向资源服务器(微信)申请获取资源;
第6步:资源服务器(微信)确认令牌无误后,同意向客户端开放资源;
角色
Third-party application:第三方应用程序,又称"客户端"(client),即例子中的"Gitee"。
HTTP service:HTTP服务提供商,简称"服务提供商",即例子中的微信。
Resource Owner:资源所有者,又称"用户",也就是你(user)。
User Agent:用户代理,比如浏览器。
Authorization server:授权服务器,即服务提供商专门用来处理认证授权的服务器。
Resource server:资源服务器,即服务提供商存放用户生成的资源的服务器。它与授权服务器,可以是同一台服务器,也可以是不同的服务器。
OAuth的作用就是让"客户端"安全可控地获取"用户"的授权,与"服务提供商"进行交互。
认证流程
(A)用户打开客户端以后,客户端要求用户给予授权。
(B)用户同意给予客户端授权。
(C)客户端使用上一步获得的授权,向认证服务器申请令牌。
(D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。
(E)客户端使用令牌,向资源服务器申请获取资源。
(F)资源服务器确认令牌无误,同意向客户端开放资源。
上面六个步骤之中,B是关键,即用户怎样才能给于客户端授权。有了这个授权以后,客户端就可以获取令牌,进而凭令牌获取资源。
令牌的特点
令牌又时效性,一般是短期的,且不能修改,密码一般是长期有效的
令牌可以由颁发者撤销,且即时生效,密码一般可以不用修改而长期有效
令牌可以设定权限的范围,且使用者无法修改
在使用令牌时需要保证令牌的保密,令牌验证有效即可进入系统,不会再做其他的验证。
OAuth2.0授权模式
客户端必须得到用户的授权(authorization grant),才能获得令牌(access token)。OAuth 2.0一共分成四种授权类型(authorization grant)
授权码模式(authorization code)
简化模式(implicit)
密码模式(resource owner password credentials)
客户端模式(client credentials)
授权码模式和密码模式比较常用。
授权码模式
授权码(authorization code)方式,指的是第三方应用先申请一个授权码,然后再用该码获取令牌。
这种方式是最常用的流程,安全性也最高,它适用于那些有后端的 Web 应用。授权码通过前端传送,令牌则是储存在后端,而且所有与资源服务器的通信都在后端完成。这样的前后端分离,可以避免令牌泄漏。
适用场景:目前主流的第三方验证都是采用这种模式
主要流程:
(A)用户访问客户端,后者将前者导向授权服务器。
(B)用户选择是否给予客户端授权。
(C)用户给予授权,授权服务器将用户导向客户端事先指定的"重定向URI"(redirection URI),同时附上一个授权码。
(D)客户端收到授权码,附上早先的"重定向URI",向授权服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。
(E)授权服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。
请求示例:
(A)步骤:客户端申请认证的URI
https://www.example.com/v1/oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&scope=read&state=xxx
参数说明:
参数类型 | 说明 |
response_type | 授权类型,必选项,此处的值固定为"code" |
client_id | 客户端的ID,必选项 |
redirect_uri | 重定向URI,认证服务器接受请求之后的调转连接,可以根据这个连接将生成的授权码回传,必选项 |
scope | code发送给资源服务器申请的权限范围,可选项 |
state | 任意值,认证服务器会原样返回,用于抵制CSRF(跨站请求伪造)攻击。 |
(C)步骤:服务器回应客户端的URI
https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=xxx
参数说明:
参数类型 | 说明 |
code | 授权码,必选项。授权码有效期通常设为10分钟,一次性使用。该码与客户端ID、重定向URI以及用户,是一一对应关系。 |
state | 原样返回客户端传的该参数的值 |
(D)步骤:客户端向认证服务器申请令牌
https://www.example.com/v1/oauth/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=CALLBACK_URL
参数说明:
参数类型 | 说明 |
client_id | 表示客户端ID,必选项 |
client_secret | 表示安全参数,只能在后端发请求 |
grant_type | 表示使用的授权模式,必选项,此处的值固定为"authorization_code" |
code | 表示上一步获得的授权码,必选项 |
redirect_uri | 表示重定向URI,必选项,且必须与A步骤中的该参数值保持一致 |
(E)步骤:响应(D)步骤的数据
{
"access_token":访问令牌,
"token_type":"bearer",
"expires_in":过期时间,
"refresh_token":"REFRESH_TOKEN",
"scope":"read",
"uid":用户ID,
"info":{...}
}
参数说明:
参数类型 | 说明 |
access_token | 访问令牌,必选项 |
token_type | 令牌类型,该值大小写不敏感,必选项 |
expires_in | 过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间 |
refresh_token | 更新令牌,用来获取下一次的访问令牌,可选项 |
scope | 权限范围,如果与客户端申请的范围一致,此项可省略 |
简化(隐式)模式
有些 Web 应用是纯前端应用,没有后端。必须将令牌储存在前端。RFC 6749 就规定了第二种方式,允许直接向前端颁发令牌,这种方式没有授权码这个中间步骤,所以称为(授权码)"隐藏式"(implicit)
简化模式不通过第三方应用程序的服务器,直接在浏览器中向授权服务器申请令牌,跳过了"授权码"这个步骤,所有步骤在浏览器中完成,令牌对访问者是可见的,且客户端不需要认证。
这种方式把令牌直接传给前端,是很不安全的。因此,只能用于一些安全要求不高的场景,并且令牌的有效期必须非常短,通常就是会话期间(session)有效,浏览器关掉,令牌就失效了。
(A)客户端将用户引导向认证服务器。
(B)用户决定是否给于客户端授权。
(C)假设用户给予授权,认证服务器将用户导向客户端指定的”重定向URI",并在URI的Hash部分包含了访问令牌。
(D)浏览器向资源服务器发出请求,其中不包括上一步收到的Hash值。
(E)资源服务器返回一个网页,其中包含的代码可以获取Hash值中的令牌。
(F)浏览器执行上一步获得的脚本,提取出令牌。
(G)浏览器将令牌发给客户端。
密码模式
如果你高度信任某个应用,RFC 6749 也允许用户把用户名和密码,直接告诉该应用。该应用就使用你的密码,申请令牌,这种方式称为"密码式"(password)。
在这种模式中,用户必须把自己的密码给客户端,但是客户端不得储存密码。这通常用在用户对客户端高度信任的情况下,比如客户端是操作系统的一部分,或者由一个著名公司出品。而授权服务器只有在其他授权模式无法执行的情况下,才能考虑使用这种模式。
适用场景:公司搭建的授权服务器
(A)用户向客户端提供用户名和密码。
(B)客户端将用户名和密码发给认证服务器,向后者请求令牌。
(C)认证服务器确认无误后,向客户端提供访问令牌。
客户端模式
客户端模式(Client Credentials Grant)指客户端以自己的名义,而不是以用户的名义,向"服务提供商"进行 授权。
适用于没有前端的命令行应用,即在命令行下请求令牌。一般用来提供给我们完全信任的服务器端服务。
(A)客户端向认证服务器进行身份认证,并要求一个访问令牌。
(B)认证服务器确认无误后,向客户端提供访问令牌。
OAuth2.0协议流程
应用场景
原生app授权:app登录请求后台接口,为了安全认证,所有请求都带token信息,如果登录验证、 请求后台数据。
前后端分离单页面应用:前后端分离框架,前端请求后台数据,需要进行oauth2安全认证
第三方应用授权登录,比如QQ,微博,微信的授权登录。(本系列课程应用场景讲解)
步骤解读:
第1步:浏览器打开Gitee码云,点击微信方式授权登录,重定向到微信授权服务页面等待获取授权码;
第2步:用户打开手机登录微信扫描“二维码”,点击“允许”授权,将重定向到客户端(Gitee)应用提供的URI;
第3步:客户端(Gitee)使用上一步获取的授权码,向微信授权服务器申请令牌(Token);
第4步:微信授权服务器对客户端(Gitee)进行认证以后,确认无误,同意发放令牌;
第5步:客户端使用令牌向资源服务器(微信)申请获取资源;
第6步:资源服务器(微信)确认令牌无误后,同意向客户端开放资源;
角色
Third-party application:第三方应用程序,又称"客户端"(client),即例子中的"Gitee"。
HTTP service:HTTP服务提供商,简称"服务提供商",即例子中的微信。
Resource Owner:资源所有者,又称"用户",也就是你(user)。
User Agent:用户代理,比如浏览器。
Authorization server:授权服务器,即服务提供商专门用来处理认证授权的服务器。
Resource server:资源服务器,即服务提供商存放用户生成的资源的服务器。它与授权服务器,可以是同一台服务器,也可以是不同的服务器。
OAuth的作用就是让"客户端"安全可控地获取"用户"的授权,与"服务提供商"进行交互。
案例解读
案例代码多我就不一 一展示啦!