oAuth意义
oAuth是open authorization的缩写。本质是在不暴露用户密码的情况下,授权第三方访问资源。
类比生活中的例子
在生活中,我们经常点外卖。也会遇到外卖小哥在送外卖的时候,被保安拦住,得等保安打电话向业主确认真的有点那家外卖之后,才放行或给予临时钥匙的情况。
在这种情况下,外卖小哥就是想要访问资源的第三方,保安就是authorization server (AS),而我们就是resource owner。
为什么要引入授权码
上面生活中的例子,很完美地解决了问题。但是在互联网的世界,并不这般如意,因此也不能照搬照抄地复制上面的做法。具体有以下限制 :
浏览器页面只能显示一个 & Http协议是单向的
在上面的生活例子,之所以能这样做,是因为外卖小哥会一直阻塞地等保安回复。
而在互联网世界,在保安 (AS) 要向颁发token之前,没登录的用户必须先登录。登录过后,也得用户点击按钮来授权资源。所以前端的页面必定是不断跳转的。
Http协议是单向的无状态协议。只有浏览器端主动连接到服务器端,而服务器端是无法主动找到浏览器端的。在前端不发起请求的情况下,后端无法通知前端。所以最终回到第三方页面,也只能通过redirect回去。
所以最终必须是携带着信息跳转回到第三方页面。
token一旦暴露在前端,就没有安全可言
在生活例子中,保安把临时钥匙给外卖小哥就好了。但是在互联网中,客户端是很危险的一个地方。
而像上面所说,最终要通知客户端,必须redirect回来,而redirect回来相当于把信息暴露在浏览器地址栏,是非常不安全的。所以redirect回来的信息只能是一次性的,有效期短的,这样才能防止黑客暴力破解。
而最终的token,也必须只能在后端之间传递。
最终流程
准备阶段
- 第三方网站先去authorization server注册,提供一到多个redirect url
- authorization server给予client id & client secrets
- 第三方网站将client id配置在前端,将client id & client secrets配置在后端
具体调用流程 (e.g. login stackoverflow with github)
-
用户在stackoverflow页面点击”login with github”
这里会传redirect url,但这并不意味着你传什么,github真的会把授权码redirect到这个url。这里的redirect url是为了validation的。这样可以防止攻击者使用钓鱼手段让用户点击一个含有redirect_uri参数,但指向攻击者控制的server的连接。
-
去到github页面
-
若没登录,要先登录
-
登录后,问用户是否同意授权
-
用户同意授权后,redirect回注册的url,携带授权码
-
stackoverflow以授权码call自己的后端
-
后端以code & client id & client secrets请求github,拿token
-
github返回token给stackoverflow后端
-
stackoverflow后端以该token请求github资源
token的优势
假如token真的泄露了,那也比直接泄露用户名和密码强。因为:
- token是有效期的,并且一般有效期很短,几秒钟到几分钟,短期的,到期就自动失效。
- token可以被用户主动撤销而失效
- token可以访问的数据是有权限控制的,是有限的权限。