OAuth2.0

什么是OAuth2

我们都知道,很多网站登录的时候,可以通过微信、QQ、微博等APP扫码扫码认证登录,其实这就是OAuth2的应用。

但是这里我想说明的是oauth2是一种授权许可。它的核心本质是用于授权,获取用户的资源信息,而不是用于登录。登录是它的附加产物。这个细节我们一定要理解清楚,以便于后续理解整个OAuth2时,不会让自己无法理清它的核心逻辑。

OAuth2的几种不同的“角色”

在这里让我们用“掘金”这个网站的登录来举例子吧!

  1. 资源拥有者:掘金的用户
  2. 第三方软件:掘金(有些文章叫做客户端)
  3. 授权服务:微信开放平台的授权服务
  4. 受保护的资源:微信头像、微信其他信息

OAuth2的几种类型

  1. 授权码凭据许可
  2. 资源拥有者凭据许可(账号密码类型)
  3. 客户端凭据许可
  4. 隐式许可(简单类型)

授权码凭据许可

官方流程

OAuth2官方流程.png

不知道你们是什么感受,反正我看官方的图,我觉得我理解能力有限,不知道整个流程到底是咋样的。

掘金登录流程

我们还是以掘金网站为案例,以下是登录掘金的全流程:

  1. 用户打开掘金
  2. 用户点击登录(微信登录)
  3. 界面跳转到微信扫码页面
  4. 用户扫码登录
  5. 用户授权并同意
  6. 登录成功,页面跳转回掘金

掘金登录详细流程

以上是我们用户能感知到的全流程,但是整个流程的服务交互,我们仍然不知道。下面我再以服务交互的角度,更详细描述下整个登录流程:

  1. 用户打开浏览器,打开掘金
  2. 用户点击登录
  3. 页面跳转到微信扫码页面
  4. 微信授权服务校验掘金的请求信息
  5. 用户用微信扫码
  6. 用户用微信授权并同意
  7. 微信授权服务校验用户信息
  8. 页面跳转到掘金前端页面并附带上授权码
  9. 掘金前端用授权码请求掘金后端
  10. 掘金后端调用微信的OpenApi请求访问令牌
  11. 微信授权服务校验授权码及掘金的请求信息,并响应访问令牌
  12. 掘金后端拿到访问令牌,并通过访问令牌获取用户信息(用户唯一ID、微信头像,用户名等)
  13. 掘金后端记录用户登录
  14. 掘金后端响应前端用户登录成功
  15. 掘金前端给用户展示登录成功页面

通过以上来看,整个流程真的挺复杂的,步骤繁多。所以我用时序图给大家画出来这一切的交互

掘金OAuth2登录流程.png

我们需要重点关注的几个步骤

  • 第三点与第四点(跳转到微信扫码登录页)

    当我们从掘金跳转到微信扫码页面的时候,我们可以观察下微信扫码页面的URL

    https://open.weixin.qq.com/connect/qrconnect?appid=wx1f78f78832fc2c16&redirect_uri=https%3A%2F%2Fjuejin.im%2Fpassport%2Fauth%2Flogin_success&response_type=code&scope=snsapi_login&state=0d26ae7d3gASoVCgoVPZIDU5OTlkODY2ZDg1MTA1YmJkYjhjOTY4NzI4Y2VkMzYzoU6-aHR0cHM6Ly9qdWVqaW4uaW0vb2F1dGgtcmVzdWx0oVYBoUkAoUQAoUHRCjChTdEKMKFIqWp1ZWppbi5pbaFSBKJQTNEDQaZBQ1RJT06goUyyaHR0cHM6Ly9qdWVqaW4uaW0voVTZIDJjNzMzMWI5YzdkMzk5MzljYjYyYjdiODllOTJlNDZioVcAoUYAolNBAKFVww%253D%253D#wechat_redirect
    

URL中有三个关键参数

  • appid:appId,第三方的唯一标识
  • redirect_uri:授权成功后的跳转URL
  • scope:权限范围

关于appId,这里稍微补充一下。当掘金需要利用微信做第三方授权登录时,掘金需要去微信的开放平台上面“注册”。这个“注册”操作,其实就是申请appId、appSecret、填写授权成功后的跳转URL、以及掘金的权限范围。

当我们跳转到微信扫码登录页的时候,会把appId、授权成功后的跳转URL、权限范围作为参数,这时微信的授权服务其实会根据appId进行一系列的校验:

  • appId是否正确(你不能随便瞎传一个appId,否则微信怎么知道是否是合法的第三方呢?)
  • 根据appId校验授权成功后的跳转URL是否正确(如果跳转的URL不是注册时填写的URL,是不被允许的)
  • 根据appId校验第三方的权限范围是否正确(第三方本次授权的权限范围不能超过它申请时的范围。比如申请时只需要查询用户信息,但是本次授权却需要查询用户好友列表,这肯定是不被微信允许的)

当验证信息通过后,微信授权页面才会打开,展示用户扫码的页面。

  • 第七点(校验用户授权信息)

    当用户用微信授权并同意的时,这时用户会提交授权同意信息给微信授权服务。这时,微信授权服务主要做三个任务:

    • 验证权限范围:第三方软件可能需要用户个人信息、用户好友列表、用户所在地等权限信息,但是作为用户为了保护自己的隐私,不一定会把全部的信息给到第三方,用户可以自由选择哪些允许授权。
    • 生成授权码:当用户同意授权后,微信授权服务会为本次授权生成授权码。
    • 重定向至第三方URL:微信授权服务授权码成功后,需要告知第三方软件,它要通过跳转到第三方的URL上。
  • 第八点(授权码)

    授权码是一个非常关键的信息,它用于后续与appSecret配合,获取访问令牌。关于授权码,我们要知道的是:

    • 授权码是一次性的,用了一次之后,微信会把它作废,后续想要使用,必须使用新的授权码。
    • 授权码是有时间限制的,而且这个时间是非常短的,官方推荐是10分钟以内,而大部分授权平台授权码的有效时间一般是3~5分钟。

    这里授权码生命周期设计的如此短,而且它是一次性的,主要是为了安全。因为授权码是微信通过重定向跳转到第三方URL上的,所以授权码是直接暴露在外的。

  • 第十点(访问令牌)

    掘金想要访问到用户的资源,最终还是要通过访问令牌去请求用户的资源。授权码其实只是一个临时的通行证。获取访问令牌有三个关键参数:

    • appId:用户的唯一标识,微信授权服务需要校验第三方是否存在
    • appSecret:还记得上述我们说过,掘金需要去微信开放平台注册时的申请的appSecret吗?就是在这里用上了。
    • 授权码:第八点生成的授权码

    微信根据上述三个参数,校验第三方是否存在,appSecret是否正确,授权码是否正确来生成访问令牌。

    至于访问令牌的种类,不同的软件授权服务有不同的规则,它可以是一串UUID,也可以是JWT,我们日常使用的token都适合的。只不过大家要注意的是,OAuth2和JWT其实并没有绝对依赖的关系,不要一开始就把二者混为一谈,否则后续很容易让自己云里雾里。
    

    当掘金拿到访问令牌后,就可以访问用户资源接口,获取用户信息了。

    其实很多人不理解,为什么要弄一个授权码还弄一个访问令牌呢?直接一步到位不就好了吗?

    我们仔细看看时序图,授权码是微信通过浏览器的URL重定向告诉掘金的,所以基本上没啥安全性可言,大家都能知道它;

    而访问令牌则是掘金的后端服务器直接与微信授权服务通信,获取到的,因此它的安全性是比较好的。

    另外,有些软件授权服务不仅仅会返回访问令牌(accessToken),还会返回一个刷新令牌(refreshToken)。刷新令牌的作用其实和授权码很相似,就是通过刷新令牌获取访问令牌,而且访问令牌也是一次性的,也有有效期,只不过它的有效期会相对比较久,有些软件的刷新令牌有效期是一周。

    为什么有这个刷新令牌呢?因为访问令牌是有有效期的。假设没有刷新令牌,当访问令牌过期后,如果第三方软件还要继续获取用户资源信息,那么只有一个办法了:告诉用户访问令牌过期,让用户重新走一遍访问令牌申请流程。毫无疑问,这个用户体验是非常差的。而如果有刷新令牌,那么第三方软件可以再访问令牌过期前,在后端静默的申请一个新的访问令牌,而整个流程是用户无感知的。

    大厂获取accessToken的时序图

    • 微信

    微信授权接入文档

微信获取accessToken时序图.png
  • 支付宝

支付宝授权接入文档

支付宝获取accessToken时序图.png

资源拥有者凭据许可(账号密码类型)

关于资源拥有者凭据许可,我们可以换个方式想象一下。假设,微信把掘金收购了,也就是掘金变成了微信的,那么微信账号密码直接告诉给掘金也没关系,反正大家都是一家人,也不存在什么账号密码泄露的问题,用同一套登录服务就行了。

那么用户就能直接用微信的账号密码获取访问令牌,后续掘金获取用户资源直接利用访问令牌就可以了。

客户端凭据许可

客户端凭据许可这个类型的应用场景,其实主要是“资源拥有者被塞进了第三方软件中” 或者 “第三方软件就是资源拥有者”。它主要是通过appId与appSecret获取访问令牌直接访问用户资源。

大家可以想象一下“云存储服务器”。比如“七牛云存储”、“阿里云OSS”,我们可以用我们自己编写的软件,访问我们的云盘。而我们作为资源拥有者,与我们自己的软件合二为一。而且我们的软件与“七牛云存储”、“阿里云OSS”是直接通过后端交互访问的,所以安全性会比较好,可以直接通过appId与appSecret获取访问令牌。

隐式许可(简单类型)

这种类型其实应用的非常少,主要是用于第三方软件只有前端,没有后端的情况。因为只有前端,所以第三方软件直接嵌入浏览器中,通过浏览器与授权服务交互。这种情况,基本上就没有所谓的安全性可言了,因此也不需要appSecret了,前端直接通过appId就可以获取到accessToken。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345