OAuth
协议为用户资源的受权提供了一个安全的、开放而又简易的标准。与以往的受权方式不一样之处是OAuth
的受权不会使第三方触及到用户的账号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就能够申请得到该用户资源的受权,所以OAuth
是安全的。OAuth
是Open Authorization
的简写。sql
OAuth
自己不存在一个标准的实现,后端开发者本身根据实际的需求和标准的规定实现。其步骤通常以下:json
token
)任何身份认证,本质上都是基于对请求方的不信任所产生的。同时,请求方是信任被请求方的,例如用户请求服务时,会信任服务方。segmentfault
因此,身份认证就是为了解决身份的可信任问题。后端
在OAuth
中,简单来讲有三方:用户(这里是指属于服务方的用户
)、服务方、第三方应用。缓存
服务方不信任用户,因此须要用户提供密码或其余可信凭据;安全
服务方不信任第三方,因此须要第三方提供自已交给它的凭据(一般的一些安全签名之类的就是);服务器
用户部分信任第三方,因此用户愿意把自已在服务方里的某些服务交给第三方使用,但不肯意把自已在服务方的密码交给第三方;微信
在oauth2.0
的流程中,用户登陆了第三方的系统后,会先跳去服务方获取一次性用户受权凭据,再跳回来把它交给第三方,第三方的服务器会把受权凭据以及服务方给它的的身份凭据一块儿交给服务方,这样,服务方一能够肯定第三方获得了用户对这次服务的受权(根据用户受权凭据),二能够肯定第三方的身份是能够信任的(根据身份凭据),因此,最终的结果就是,第三方顺利地从服务方获取到了这次所请求的服务。app
从上面的流程中能够看出,oauth2.0
完整地解决掉了用户、服务方、第三方 在某次服务时这三者之间的信任问题。url
- Resource Owner(资源拥有者:用户)
- Client (第三方接入平台:请求者)
- Resource Server (服务器资源:数据中心)
- Authorization Server (认证服务器)
Oauth2.0基本流程:
原理很简单,用户访问App
,App
访问Authorization Server
请求权限,
Authorization Server
获得用户赞成后,返回token
,
App
经过这个token
向Authorization Server
索要数据,
App
只能从Authorization Server
这个中介获取服务器数据,而没法直接访问Resource Server
。
客户端必须获得用户的受权(authorization grant
),才能得到令牌(access token
)。OAuth 2.0
定义了四种受权方式。
- 受权码模式(
authorization code
)- 简化模式(
implicit
)- 密码模式(
resource owner password credentials
)- 客户端模式(
client credentials
)
受权码模式(authorization code
)是功能最完整、流程最严密的受权模式。它的特色就是经过客户端的后台服务器,与"服务提供商"的认证服务器进行互动。
它的步骤以下:
- 用户访问客户端,后者将前者导向认证服务器。
- 用户选择是否给予客户端受权。
- 假设用户给予受权,认证服务器将用户导向客户端事先指定的"重定向URI"(redirection URI),同时附上一个受权码。
- 客户端收到受权码,附上早先的"重定向URI",向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。
- 认证服务器核对了受权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。
下面是上面这些步骤所须要的参数。
步骤1: 客户端申请认证的URI,包含如下参数:
- response_type:表示受权类型,必选项,此处的值固定为"code"
- client_id:表示客户端的ID,必选项。(
如微信受权登陆,此ID是APPID
)- redirect_uri:表示重定向URI,可选项
- scope:表示申请的权限范围,可选项 state:表示客户端的当前状态,能够指定任意值,认证服务器会原封不动地返回这个值。
例子:
GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1 HTTP/1.1 Host: server.example.com
对比微信网页扫描受权请求CODE
https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
步骤3:服务器回应客户端的URI,包含如下参数:
- code:表示受权码,必选项。该码的有效期应该很短,一般设为10分钟,客户端
只能使用该码一次
,不然会被受权服务器拒绝。该码与客户端ID和重定向URI,是一一对应关系。- state:若是客户端的请求中包含这个参数,认证服务器的回应也必须如出一辙包含这个参数。
例子:
HTTP/1.1 302 Found Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA &state=xyz
步骤4:客户端向认证服务器申请令牌的HTTP请求,包含如下参数:
- grant_type:表示使用的受权模式,必选项,此处的值固定为"authorization_code"。
- code:表示上一步得到的受权码,必选项。
- redirect_uri:表示重定向URI,必选项,且必须与A步骤中的该参数值保持一致。
- client_id:表示客户端ID,必选项。
例子:
POST /token HTTP/1.1 Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
步骤5:认证服务器发送的HTTP回复,包含如下参数:
- access_token:表示访问令牌,必选项。
- token_type:表示令牌类型,该值大小写不敏感,必选项,能够是bearer类型或mac类型。
- expires_in:表示过时时间,单位为秒。若是省略该参数,必须其余方式设置过时时间。
- refresh_token:表示更新令牌,用来获取下一次的访问令牌,可选项。
- scope:表示权限范围,若是与客户端申请的范围一致,此项可省略。
例子:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store Pragma: no-cache { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter":"example_value" }
从上面代码能够看到,相关参数使用JSON格式发送(Content-Type: application/json
)。此外,HTTP头信息中明确指定不得缓存。
若是用户访问的时候,客户端的"访问令牌"已通过期,则须要使用"更新令牌"申请一个新的访问令牌。
客户端发出更新令牌的HTTP请求,包含如下参数:
例子:
POST /token HTTP/1.1
Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
原文连接:https://segmentfault.com/a/1190000010540911?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io