01 | OAuth 2.0是要通过什么方式解决什么问题?

你好,我是王新栋。

在课程正式开始之前,我想先问你个问题。第一次使用极客时间App的时候,你是直接使用了第三方帐号(比如微信、微博)登录,还是选择了重新注册新用户?如果你选择了重新注册用户,那你还得上传头像、输入用户名等信息。但如果你选择了使用第三方帐号微信来登录,那极客时间会直接使用你微信的这些信息作为基础信息,你就能省心很多。

到这里,我估计你会问,这是怎么实现的?微信把我的个人信息给了极客时间,它又是怎么保证我的数据安全的呢?

其实,微信这一系列授权背后的原理都可以归到一个词上,那就是OAuth 2.0。今天这节课,我们就来看看OAuth 2.0到底是什么、能干什么以及它是怎么干的。

OAuth 2.0是什么?

用一句话总结来说,OAuth 2.0就是一种授权协议。那如何理解这里的“授权”呢?

我举个咱们生活中的例子。假如你是一名销售人员,你想去百度拜访你的大客户王总。到了百度的大楼之后,保安拦住了你,问你要工牌。你说:“保安大哥啊,我是来拜访王总的,哪里有什么工牌”。保安大哥说:“那你要去前台做个登记”。

然后你就赶紧来到前台,前台美女问你是不是做了登记。你说王总秘书昨天有要你的手机号,说是已经做过预约。小姐姐确认之后往你的手机发了个验证码,你把验证码告诉了前台小姐姐之后,她给了你一张门禁卡,于是你就可以开心地去见王总了。

你看,这个例子里面就有一次授权。本来你是没有权限进入百度大楼的,但是经过前台小姐姐一系列的验证之后,她发现你确实是来拜访客户的,于是给了你一张临时工牌。这整个过程就是授权。

我再举一个电商的场景,你估计更有感觉。假如你是一个卖家,在京东商城开了一个店铺,日常运营中你要将订单打印出来以便给用户发货。但打印这事儿也挺繁琐的,之前你总是手工操作,后来发现有个叫“小兔”的第三方软件,它可以帮你高效率地处理这事。

但你想想,小兔是怎么访问到这些订单数据的呢?其实是这样,京东商城提供了开放平台,小兔通过京东商家开放平台的API就能访问到用户的订单数据。

只要你在软件里点击同意,小兔就可以拿到一个访问令牌,通过访问令牌来获取到你的订单数据帮你干活儿了。你看,这里也是有一次授权。你要是不同意,平台肯定不敢把这些数据给到第三方软件。

为什么用OAuth 2.0?

基于上面两种场景的解决方案,关于授权我们最容易想到的方案就是提供钥匙。比如,你要去百度拜访王总,那前台小姐姐就给你张百度的工牌;小兔要获取你的订单信息,那你就把你的用户名和密码给它。但稍微有些安全意识,我们都不会这样做。

因为你有了百度工牌,那以后都可以随时自由地进出了,这显然不是百度想要的。所以,百度有一套完整的机制,通过给你一张临时工牌,实现在保证安全的情况下,还能让你去大楼里面见到王总。相应地,小兔软件请求访问你的订单数据的过程,也会涉及这样一套授权机制,那就是OAuth 2.0。它通过给小兔软件一个访问令牌,而不是让小兔软件拿着你的用户名和密码,去获取你的订单数据帮你干活儿。

其实,除了小兔软件这个场景,在如今的互联网世界里用到OAuth 2.0的地方非常多,只是因为它隐藏了实现细节,需要我们多做分析才能发现它。比如,当你使用微信登录其他网站或者App的时候,当你开始使用某个小程序的时候,你都在无感知的情况下用到了OAuth 2.0。

那总结来说,OAuth 2.0这种授权协议,就是保证第三方(软件)只有在获得授权之后,才可以进一步访问授权者的数据。因此,我们常常还会听到一种说法,OAuth 2.0是一种安全协议。现在你知道了,这种说法也是正确的。

现在访问授权者的数据主要是通过Web API,所以凡是要保护这种对外的API时,都需要这样授权的方式。而OAuth 2.0的这种颁发访问令牌的机制,是再合适不过的方法了。同时,这样的Web API还在持续增加,所以OAuth 2.0是目前Web上重要的安全手段之一了。

OAuth 2.0是怎样运转的?

现在,我相信你已经对OAuth 2.0有了一个整体印象,接下来咱们再看看它是怎么运转的。

我们还是来看上面提到的小兔打单软件的例子吧。假如小明在京东上面开了一个店铺,小明要管理他的店铺里面的订单,于是选择了使用小兔软件。

现在,让我们把“小明”“小兔软件”“京东商家开放平台”放到一个对话里面,看看“他们”是怎么沟通的吧。

小明:“你好,小兔软件。我正在Google浏览器上面,需要访问你来帮我处理我在京东商城店铺的订单。”

小兔软件:“好的,小明,我需要你给我授权。现在我把你引导到京东商家开放平台上,你在那里给我授权吧。”

京东商家开放平台:“你好,小明。我收到了小兔软件跳转过来的请求,现在已经准备好了一个授权页面。你登录并确认后,点击授权页面上面的授权按钮即可。”

小明:“好的,京东商家开放平台。我看到了这个授权页面,已经点授权按钮啦😄”

京东商家开放平台:“你好,小兔打单软件。我收到了小明的授权,现在要给你生成一个授权码code值,我通过浏览器重定向到你的回调URL地址上面了。”

小兔软件:“好的,京东商家开放平台。我现在从浏览器上拿到了授权码,现在就用这个授权码来请求你,请给我一个访问令牌access_token吧。”

京东商家开放平台:“好的,小兔打单软件,访问令牌已经发送给你了。”

小兔打单软件:“太好了,我现在就可以使用访问令牌来获取小明店铺的订单了。”

小明:“我已经能够看到我的订单了,现在就开始打单操作了。”

下面,为了帮助你理解,我再用一张图来描述整个过程:

再分析下这个流程,我们不难发现小兔软件最终的目的,是要获取一个叫做“访问令牌”的东西。从最后一步也能够看出来,在小兔软件获取到访问令牌之后,才有足够的 “能力” 去请求小明的店铺的订单,也就是才能够帮助小明打印订单。

那么,小兔软件是怎么获取访问令牌的值的呢?我们会发现还有一个叫做“授权码”的东西,也就是说小兔软件是拿授权码换取的访问令牌

小兔软件又是怎么拿到授权码的呢?从图中流程刚开始的那一步,我们就会发现,是在小明授权之后,才产生的授权码,上面流程中后续的一切动作,实际上都是在小明对小兔软件授权发生以后才产生的。其中主要的动作,就是生成授权码–>生成访问令牌–>使用访问令牌。

到这里,我们不难发现,OAuth 2.0 授权的核心就是颁发访问令牌、使用访问令牌,而且不管是哪种类型的授权流程都是这样。你一定要理解,或者记住这句话,它是整个流程的核心。你也可以再回想下,去百度拜访王总的例子。如果你是百度这套机制的设计者的话,会怎么设计这套授权机制呢。想清楚了这个问题,你再去理解令牌、授权码啥的也就简单了。

在小兔软件这个例子中呢,我们使用的就是授权码许可(Authorization Code)类型。它是OAuth 2.0中最经典、最完备、最安全、应用最广泛的许可类型。除了授权码许可类型外,OAuth 2.0针对不同的使用场景,还有3种基础的许可类型,分别是隐式许可(Implicit)、客户端凭据许可(Client Credentials)、资源拥有者凭据许可(Resource Owner Password Credentials)。相对而言,这3种授权许可类型的流程,在流程复杂度和安全性上都有所减弱(我会在第6讲,与你详细分析)。

因此,在这个课程中,我会频繁用授权码许可类型来举例。至于为什么称它为授权码许可,为什么有两次重定向,以及这种许可类型更详细的通信流程又是怎样的,我会在第2讲给你深入分析,你可以先不用关注。

总结

好了,今天这节课就到这里。这节课咱们知识点不多,我来回给你举例子,其实就是希望你能理解OAuth到底是什么,为什么需要它,以及它大概的运行逻辑是怎样的。总结来说,我需要你记住以下这3个关键点:

  1. OAuth 2.0的核心是授权许可,更进一步说就是令牌机制。也就是说,像小兔软件这样的第三方软件只有拿到了京东商家开放平台颁发的访问令牌,也就是得到了授权许可,然后才可以代表用户访问他们的数据。

  2. 互联网中所有的受保护资源,几乎都是以Web API的形式来提供访问的,比如极客时间App要获取用户的头像、昵称,小兔软件要获取用户的店铺订单,我们说OAuth 2.0与安全相关,是用来保护Web API的。另外,第三方软件通过OAuth 2.0取得访问权限之后,用户便把这些权限委托给了第三方软件,我们说OAuth 2.0是一种委托协议,也没问题。

  3. 也正因为像小兔这样的第三方软件,每次都是用访问令牌而不是用户名和密码来请求用户的数据,才大大减少了安全风险上的“攻击面”。不然,我们试想一下,每次都带着用户名和密码来访问数量众多的Web API ,是不是增加了这个“攻击面”。因此,我们说OAuth 2.0的核心,就是颁发访问令牌和使用访问令牌。

思考题

好了,今天这一讲我们马上要结束了,我给你留个思考题。

你可以再花时间想下小兔软件获取用户订单信息的那个场景,如果让你来设计整个的授权流程,你会怎么设计?还有没有更好的方式?

欢迎你在留言区分享你的观点,也欢迎你把今天的内容分享给其他朋友,我们一起交流。

精选留言

  • inrtyx

    2020-06-29 21:05:17

    为什么要用授权码换取token,而不是直接获取token?
    作者回复

    直接获取token的场景是有的,客户端凭据许可类型就是这样的使用场景,但是我们会在课程里面讲到,授权码许可类型是OAuth 2.0 最安全 最完备的许可类型。

    以Web场景为例,第一次用户是跟第三方软件建立的“联系”,三方软件要把用户引导到平台一方去授权,这个时候用户实际上跟三方软件就失去了“联系”,平台如果这个时候直接把令牌给了三方软件,因为没了“联系”,三方软件就不能很方便的告诉用户。

    关于这块更详细的内容在后面课程会着重讲到。

    2020-06-29 23:39:03

  • Geek_aceb32

    2020-06-30 21:12:30

    我有个疑问,小兔把客户引导到京东开放平台上,如果小兔是恶意的,做了一个和京东一样的网页让用户授权,一般用户难以仔细区分,小兔不就能拿到用户的密码了吗?
    作者回复

    第三方应用在官方平台上注册的时候是要签订协议的,你说的这点就属于监守自盗了,只能靠法律法规来惩治。
    另外,授权服务做登录的时候,当前一般都是采用App扫码登录,只要培养了用户这样的习惯,也能规避一大部分风险发生的概率。

    2020-07-05 22:54:42

  • gavin

    2020-06-29 17:54:48

    这里的授权服务和受保护资源服务都是京东商家开放平台(不过应该是对应授权服务和订单服务)、客户端(第三方软件)对应的是小兔软件、资源的拥有者小明通过OAuth2.0的授权码模式授权后,小兔软件可以访问对应的订单,这里有两个点,需要老师给指点一下是否理解的正确:
    1. 授权码模式我一直理解其比Implicit模式的安全性主要体现在,其访问令牌是基于再次的https请求的返回值,是加密传递的,而Implicit模式的授权码是get请求参数跳转返回的,所以安全性不高。
    2. OAuth2.0的授权是基于scope实现的,一个scope值会对应一些可以访问的资源,在小兔软件请求获取授权时,要声明对应scope,小明在授权页面上能够清楚的看到授权的scope是什么,对应的返回的访问凭据也应该包含scope信息。
    而且凭据中也包含了小明的身份信息,这样最终授权访问的就是scope对应的小明的相关资源。
    作者回复

    理解的很详细,我分别补充一些:
    1、Implicit模式相当于是一个“裸”的状态,当然OAuth 2.0 是建议要通信在HTTPS的环境下,四种授权模式中最安全的就是授权码许可,令牌端点的通信是通过后端通信;
    2、这里你说的“访问凭据”就是指TOKEN了,TOKEN和SCOPE的映射关系会在授权服务一侧保存;

    2020-06-30 22:04:41

  • Jaswine

    2020-06-29 18:32:35

    访问百度的案例中有以下角色:我(client),前台王小姐(百度的授权、鉴权服务),大客户王总(资源),百度(资源所在的服务器)。
  • Edison鹏

    2020-08-02 21:35:55

    我的理解:1.通过第三方应用授权通过拿到的token和用户主动登录开放平台所获得的token是两个独立的token?
    作者回复

    第三方软件能够拿到token的前提是,用户必须授权,用户授权的前提是,用户必须先登录。

    2020-08-03 08:45:54

  • 宝宝太喜欢极客时间了

    2020-07-03 08:08:01

    令牌跟sessionId有什么本质区别?
    作者回复

    前者是授权,后者是认证,后面我们会详细讲,授权和认证的区别,在这里我先提前说一下:OAuth 2.0 是授权协议,不是身份认证协议。

    2020-07-03 13:50:18

  • baitaoccb

    2020-06-29 22:18:04

    请问为什么授权者授权后,不直接返回令牌?而是先返回授权码,然后第三方软件再通过授权码得到令牌?
    作者回复

    以Web场景为例,第一次用户是跟第三方软件建立的“联系”,三方软件要把用户引导到平台一方去授权,这个时候用户实际上跟三方软件就失去了“联系”,平台如果这个时候直接把令牌给了三方软件,因为没了“联系”,三方软件就不能很方便的告诉用户,关于这块更详细的内容在后面课程会着重讲到。

    2020-06-29 23:28:18

  • 兰正浩

    2020-06-30 12:27:36

    如何确保小兔软件只访问订单数据?
    作者回复

    这个可以通过SCOPE来约束,权限控制也是OAuth 2.0实践过程中需要重点处理的,在后面的课程中都会有涉及到。

    2020-06-30 21:46:55

  • iLeGeND

    2020-06-29 20:58:05


    为什么直接用授权码 还弄个令牌
  • 杯莫停

    2021-03-23 18:42:54

    比如极客时间可以用微信登录,点击微信图标,极客时间会重定向到一个有微信登录二维码的页面,让我扫二维码,我扫了就是授权微信给极客时间提供授权服务。然后微信会给极客时间发授权码,极客时间收到授权码,去微信提供的api获取token。获取到token,极客时间就可以获取到我的微信头像,昵称,甚至通讯录(不知道会不会)大概是这个流程吧?
  • 蒋胜琳

    2020-07-13 22:05:59

    总结得很好,例子也不错,特别喜欢先粗讲实习原理及流程的课程,对新手很友好,容易建立起体系知识
  • 扎紧绷带

    2020-07-01 10:54:41

    栋哥,我要提一个比较超前的问题,因为现在正在做一个开放平台,目前用到密码模式,第三方客户端可以通过我们平台的账号密码,访问一些数据。我的问题是,这个密码该怎样加密?可以简单说下吗
    作者回复

    密码怎样加密最终还都是传输的保护【密码】的信息,当然可以采用非对称的加密算法,另外呢,加密的重点不在于加密算法本身,因加密算法无外乎刚才说的非对称和对此,重点地方在于如何管理秘钥,需要有一个秘钥管理系统。另外还是建议采用其它的授权许可类型。

    2020-07-02 09:27:37

  • iLeGeND

    2020-06-30 07:22:23

    oauth2 一种规范或者解决方案,还是框架?
    作者回复

    规范、解决方案、框架 都有他的语境含义,也就是说在一定情况下都没有问题,都合理。比如 规范,那么它是一种授权协议规范,在协议后面加上规范没有问题;解决方案,保护Web Api的一种解决方案,没有问题;框架,授权框架,在这个框架下包含了四种角色,我们的生产组件承担了里面的角色,也没有问题。

    2020-06-30 21:56:10

  • 星夜宝宝

    2020-06-29 20:07:55

    老师能写弄一个spring boot版本的吗?
    作者回复

    我们的附属例子是想用最原生的代码,来讲透OAuth 2.0的流程体系,带着“衣服”的例子,会干扰原理的讲解。

    2020-06-29 23:30:38

  • Seven.Lin澤耿

    2020-06-29 17:27:19

    我们项目使用OAuth2.0 ,但是还是使用账号密码登录,是不是等于没有用授权的特性了==、
    作者回复

    没错,使用OAuth 2.0 的核心目的就是令牌,通过令牌来代替账号密码,这样可以减少【攻击面】,那么如果还继续使用账号和密码,当然就没有利用到OAuth 2.0。

    2020-06-30 22:12:32

  • 暖色浮余生

    2020-06-30 22:03:20

    最近刚好在学习这个OAuth2。觉得很绕,搞不懂各种模式应该应用在哪一种场景下,感觉这个课就是个救星啊哈哈。
    作者回复

    感谢支持

    2020-07-02 13:28:11

  • 胡化敏

    2020-06-29 17:26:50

    故事讲的不错
    作者回复

    谢谢 化敏同学。其实故事的背后还有故事,😀

    2020-06-29 23:56:29

  • 曙光

    2020-09-12 16:45:59

    安全基本不同,授权方式不通。如果商家的用户名密码被盗用,页面跳转,授权码没办法保护商家了。可以再添加手机验证码验证商家信息,如果金额较高或打单数量较大,可以增加U盾来提升安全性。当然,也可以通过人脸识别,安全性高,使用方便。
    如果小兔是京东商城自家应用,本身的安全级别就高,点击一次授权即可获取访问令牌
  • 在路上

    2020-07-18 11:03:47

    王老师,小兔三方软件拿到的令牌一般是多久,每次都需要重新授权,还是周期性的 一天 一周 一月 一年这种
    作者回复

    在我们给的小兔三方软件的例子中是小明购买之后来进行使用的,小兔拿到的令牌时长跟订购有关系。

    一般应用小时级就可以,比如微信给的是2小时,超过之后用刷新令牌获取。

    2020-07-19 09:17:32

  • 慎独明强

    2020-07-17 22:24:04

    OAuth2.0是开放授权协议,通过用户登录后,再去授权给第三方,开放平台会给第三方erp系统一个授权认证码,第三方erp再与开放平台系统进行认证,颁发一个Access token访问令牌,令牌会有过期时间,第三方erp拿到令牌,再使用令牌请求拉单接口,就可以通过开放平台的认证访问到我们订单系统的订单数据。之前自己负责订单这块,给开放平台提供拉单接口,老师讲的这个例子,很生动。
    作者回复

    感谢支持

    2020-07-19 09:18:16