定义
OAuth是一种授权机制,数据的所有者告诉系统,同意授权第三方应用进入系统,获取这些数据。系统从而产生一个短期的进入令牌(token),用来代替密码,供第三方应用使用。
例子
举个例子,京东App要求访问我的微信头像和昵称,这里面,我是数据的所有者,而微信就是服务提供商,也就是上面的系统,而京东就是第三方的客户端。
当京东要求获取我的微信数据时,我不会将我的微信账号和密码直接告诉京东,然后让京东自己去登陆我的微信账号去获取对应的数据,因为这样做会有以下的缺点:
- 京东也许会保存我的密码,这样很不安全
- 京东通过密码能够获取我在微信的全部数据,我没有办法限制京东能获得哪些数据、不能获得哪些数据
- 我除了修改密码之外,没有能够取消京东获取我的微信数据的能力
- 只要有一个京东这样的、知晓我的密码的第三方APP被破解,我的微信密码就会泄露
所以京东需要通过OAuth这种授权机制来获得我的微信数据。思路是这样的:
- 京东在它的APP里选择以微信账号登陆京东APP;
- 京东客户端会跳转到微信设置的认证服务器,向我询问是否允许获取我的微信相关资料;
- 当我同意之后,微信的认证服务器就会向京东APP颁发登陆令牌(token),这个token与用户密码不同,并且在登陆的时候可以指定token的权限范围有效期;
- 京东APP获得令牌后,就可以向微信的资源服务器来申请获取用户的微信资料,微信的资源服务器根据令牌的权限和有效期向京东APP开放我的微信头像和昵称。
授权模式
OAuth的核心就是向第三方应用颁发令牌,OAuth 2.0定义了四种授权方式来让客户端得到用户的授权:
- 授权码(authorization-code)
- 隐藏式(implicit)
- 密码式(password)
- 客户端凭证(client credentials)
以上这些授权方式,第三方应用在申请令牌之前,都必须先到系统备案,说明自己的身份,然后会拿到两个身份识别码:客户端ID(client ID)和客户端密钥(client secret)。
授权码模式
授权码(authorization-code)模式,指的是第三方应用先申请授权码,然后用该授权码获取令牌。
这种方式是最常用的,也是安全性最高的,适用于后后端的Web应用。授权码通过前端传送,令牌存储在后端,所有与资源服务器的通信都在后端完成。这样的前后端分离可以避免令牌泄露。
仍旧以京东和微信举例
(1)第一步,当用户点击京东APP以微信登陆的链接后,就会跳转到微信的认证服务器,下面就是一个示意的跳转链接:
https://weixin.com/oauth/authorize?
response_type=code&
client_id=CLIENT_ID&
redirect_uri=CALLBACK_URL&
scope=read
weixin.com/oauth/authorize
就是微信认证服务器的URL,response_type
参数表示要求返回授权码(code
),client_id
参数用来表明客户端的ID,redirect_uri
是认证服务器接受或拒接请求后的跳转网址,scope
参数表示请求的授权范围
(2)第二步,用户跳转到认证服务器的页面后,会要求用户登录,然后询问是否同意给京东APP授权。用户表示同意后,认证服务器就会调回redirect_uri
参数指定的网址,在跳转时会以URL中的query
参数的形式传回一个授权码(code
)
https://jd.com/callback?code=AUTHORIZATION_CODE
上面的URL中,code
参数对应的值就是授权码
(3)第三步,京东拿到授权码后,就可以在后端向微信认证服务器请求令牌(token)
https://weixin.com/oauth/token?
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET&
grant_type=authorization_code&
code=AUTHORIZATION_CODE&
redirect_uri=CALLBACK_URL
上面URL中,client_id
和client_secert
参数用来让认证服务器确认京东APP的身份(client_secret
是保密的,所以只能在后端发送请求),grant_type
参数的值是AUTHORIZATION_CODE
,表示采用的授权方式是授权码,code
参数是上一步拿到的授权码,redirect_uir
参数是令牌颁发后的回调地址。
(4)第四步,微信认证服务器收到请求后,核对信息后就会办法令牌,具体的做法是向redirect_uri
指定的网址发送一段JSON数据:
HTTP/1.1 200 OK
Conten