我们都知道,很多网站登录的时候,可以通过微信、QQ、微博等APP扫码扫码认证登录,其实这就是OAuth2的应用。
但是这里我想说明的是oauth2是一种授权许可。它的核心本质是用于授权,获取用户的资源信息,而不是用于登录。登录是它的附加产物。这个细节我们一定要理解清楚,以便于后续理解整个OAuth2时,不会让自己无法理清它的核心逻辑。
在这里让我们用“掘金”这个网站的登录来举例子吧!
OAuth2官方流程.png
不知道你们是什么感受,反正我看官方的图,我觉得我理解能力有限,不知道整个流程到底是咋样的。
我们还是以掘金网站为案例,以下是登录掘金的全流程:
以上是我们用户能感知到的全流程,但是整个流程的服务交互,我们仍然不知道。下面我再以服务交互的角度,更详细描述下整个登录流程:
通过以上来看,整个流程真的挺复杂的,步骤繁多。所以我用时序图给大家画出来这一切的交互
掘金OAuth2登录流程.png
URL中有三个关键参数
关于appId,这里稍微补充一下。当掘金需要利用微信做第三方授权登录时,掘金需要去微信的开放平台上面“注册”。这个“注册”操作,其实就是申请appId、appSecret、填写授权成功后的跳转URL、以及掘金的权限范围。
当我们跳转到微信扫码登录页的时候,会把appId、授权成功后的跳转URL、权限范围作为参数,这时微信的授权服务其实会根据appId进行一系列的校验:
当验证信息通过后,微信授权页面才会打开,展示用户扫码的页面。
这里授权码生命周期设计的如此短,而且它是一次性的,主要是为了安全。因为授权码是微信通过重定向跳转到第三方URL上的,所以授权码是直接暴露在外的。
微信根据上述三个参数,校验第三方是否存在,appSecret是否正确,授权码是否正确来生成访问令牌。
至于访问令牌的种类,不同的软件授权服务有不同的规则,它可以是一串UUID,也可以是JWT,我们日常使用的token都适合的。只不过大家要注意的是,OAuth2和JWT其实并没有绝对依赖的关系,不要一开始就把二者混为一谈,否则后续很容易让自己云里雾里。
其实很多人不理解,为什么要弄一个授权码还弄一个访问令牌呢?直接一步到位不就好了吗?
而访问令牌则是掘金的后端服务器直接与微信授权服务通信,获取到的,因此它的安全性是比较好的。
为什么有这个刷新令牌呢?因为访问令牌是有有效期的。假设没有刷新令牌,当访问令牌过期后,如果第三方软件还要继续获取用户资源信息,那么只有一个办法了:告诉用户访问令牌过期,让用户重新走一遍访问令牌申请流程。毫无疑问,这个用户体验是非常差的。而如果有刷新令牌,那么第三方软件可以再访问令牌过期前,在后端静默的申请一个新的访问令牌,而整个流程是用户无感知的。
微信授权接入文档
微信获取accessToken时序图.png
支付宝授权接入文档
支付宝获取accessToken时序图.png
关于资源拥有者凭据许可,我们可以换个方式想象一下。假设,微信把掘金收购了,也就是掘金变成了微信的,那么微信账号密码直接告诉给掘金也没关系,反正大家都是一家人,也不存在什么账号密码泄露的问题,用同一套登录服务就行了。
那么用户就能直接用微信的账号密码获取访问令牌,后续掘金获取用户资源直接利用访问令牌就可以了。
客户端凭据许可这个类型的应用场景,其实主要是“资源拥有者被塞进了第三方软件中” 或者 “第三方软件就是资源拥有者”。它主要是通过appId与appSecret获取访问令牌直接访问用户资源。
大家可以想象一下“云存储服务器”。比如“七牛云存储”、“阿里云OSS”,我们可以用我们自己编写的软件,访问我们的云盘。而我们作为资源拥有者,与我们自己的软件合二为一。而且我们的软件与“七牛云存储”、“阿里云OSS”是直接通过后端交互访问的,所以安全性会比较好,可以直接通过appId与appSecret获取访问令牌。
这种类型其实应用的非常少,主要是用于第三方软件只有前端,没有后端的情况。因为只有前端,所以第三方软件直接嵌入浏览器中,通过浏览器与授权服务交互。这种情况,基本上就没有所谓的安全性可言了,因此也不需要appSecret了,前端直接通过appId就可以获取到accessToken。