OAuth 2.0实战课
王新栋
京东资深架构师
立即订阅
2496 人已学习
课程目录
已完结 17 讲
0/2登录后,你可以任选2讲全文学习。
开篇词 (1讲)
开篇词 | 为什么要学OAuth 2.0?
免费
基础篇 (6讲)
01 | OAuth 2.0是要通过什么方式解决什么问题?
02 | 授权码许可类型中,为什么一定要有授权码?
03 | 授权服务:授权码和访问令牌的颁发流程是怎样的?
04 | 在OAuth 2.0中,如何使用JWT结构化令牌?
05 | 如何安全、快速地接入OAuth 2.0?
06 | 除了授权码许可类型,OAuth 2.0还支持什么授权流程?
进阶篇 (8讲)
07 | 如何在移动App中使用OAuth 2.0?
08 | 实践OAuth 2.0时,使用不当可能会导致哪些安全漏洞?
09 | 实战:利用OAuth 2.0实现一个OpenID Connect用户身份认证协议
10 | 串讲:OAuth 2.0的工作流程与安全问题
11 | 实战案例:使用Spring Security搭建一套基于JWT的OAuth 2.0架构
12 | 架构案例:基于OAuth 2.0/JWT的微服务参考架构
13 | 各大开放平台是如何使用OAuth 2.0的?
14 | 查漏补缺:OAuth 2.0 常见问题答疑
结束语 (2讲)
期末测试 | 一套习题,测试你的掌握程度
结束语 | 把学习当成一种习惯
OAuth 2.0实战课
15
15
1.0x
00:00/00:00
登录|注册

03 | 授权服务:授权码和访问令牌的颁发流程是怎样的?

王新栋 2020-07-04
你好,我是王新栋。
在上一讲,我从为什么需要授权码这个问题开始,为你串了一遍授权码许可流程整体的通信过程。在接下来的三讲中,我会着重为你讲解关于授权服务的工作流程、授权过程中的令牌,以及如何接入 OAuth 2.0。这样一来,你就可以吃透授权码许可这一最经典、最完备、最常用的授权流程了,以后再处理授权相关的逻辑就更得心应手了。现在呢,让我们开始这一讲。
在介绍授权码许可类型时,我提到了很多次 “授权服务”。一句话概括,授权服务就是负责颁发访问令牌的服务。更进一步地讲,OAuth 2.0 的核心是授权服务,而授权服务的核心就是令牌。
为什么这么说呢?当第三方软件比如小兔,要想获取小明在京东店铺的订单,就必须先从京东商家开放平台的授权服务那里获取访问令牌,进而通过访问令牌来 “代表” 小明去请求小明的订单数据。这不恰恰就是整个 OAuth 2.0 授权体系的核心吗?
那么,授权服务到底是怎么生成访问令牌的,这其中包含了哪些操作呢?还有一个问题是,访问令牌过期了而用户又不在场的情况下,又如何重新生成访问令牌呢?
带着这两个问题,我们就以授权码许可类型为例,一起深入探索下授权服务这个核心组件吧。

授权服务的工作过程

开始之前,你还是要先回想下小明给小兔软件授权订单数据的整个流程。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《OAuth 2.0实战课》,如需阅读全部文章,
请订阅文章所属专栏新⼈⾸单¥9.9
立即订阅
登录 后留言

精选留言(38)

  • 申玉宝
    为什么要 通过刷新令牌让第三方不断刷新token有效期,而不是直接给访问token一个更长的有效期?后者更简单

    作者回复: 为了安全性的考虑,是不可以让“token一个更长的有效期”存在的。

    2020-07-05
    7
    4
  • 约书亚
    在上一节回答留言时,老师提到,用refresh刷新access时,如果access没过期,那会给这个access续期而不会重新生成?
    这节课没提到这个。请问这是oauth规定的么?或者一般都这样实现?
    因为我感觉无限续期会增加access被破解的风险

    作者回复: 感谢 约书亚 指正 我翻看了 之前的回复 做了修改。
    1、:若access_token未超时,那么进行refresh_token有两种方式,(1)不会改变access_token,但超时时间会刷新,相当于续期access_token(2)更新access_token的值,我们建议【统一更新access_token的值】。

    2、延期access_token并不是一个最好的方式,尽管有的开放平台是这么做的。

    3、在我们这节课中,我们是提到了这点,本文中的描述是:【用来通过系统重新请求生成一个新的访问令牌】
    而且咱们这节课的建议也是更换一个新的访问令牌。

    4、“因为我感觉无限续期会增加access被破解的风险”
    刷新令牌也有有效期。

    2020-07-05
    1
    3
  • 哈德韦
    请问什么是 rscope?和上下文中的 scope 是一回事吗?这个 r 代表什么?

    作者回复: 对应的权限 都是同一个权限,这里用rscope是受保护资源服务再次确认的权限,r是replay。

    2020-07-05
    1
    3
  • 暖色浮余生
    刷新令牌有过期时间吧,不过一般设置的时间比较长。反正微信公众号的挺长的,还有一直不明白 scope的 权限范围指的是一个什么样的范围

    作者回复: SCOPE的权限范围非常重要,OAuth 2.0 本着【最小权限范围】原则,来支持用户对第三方软件授权。比如小兔打单软件,他的主要“行当”就是帮助小明打印订单,那么它的权限范围就是调用跟订单打印相关的API,比如单条查询订单API、批量查询订单API,那么查询小明店铺其它的API就要受限,在小兔打单软件申请成为开放平台的应用的时候就要做一次权限范围的选择,另外,当小明给小兔进行授权的时候,也会让小明去选择并确认,总之就是不要让小兔打单软件有超过其正常权限的范围,来充分保护小明店铺的数据。后面的课程,我们还会详细讲解关于SCOPE的种类和用法。

    2020-07-04
    1
    3
  • 马成
    刷新令牌和授权码的处理机制感觉非常相似。只是code是第一次生成的,刷新令牌是后续生成的,功能都是换取访问令牌。我觉得这里还有一个点没说,就是在访问令牌有效期的前半段时间,使用刷新令牌换取的访问令牌是不变的。想问一下设计上可不可使用访问令牌来换取新的访问令牌?

    作者回复: 1.刷新令牌和授权码完全两个东西
    2.刷新令牌换回来的访问令牌一定是变的
    3.不可以,有2所以3不成立

    对于第2点,可能是马成看了上节课的留言回复,当时有不准确的描述,我已修改,最好的方案是:更新访问令牌的值,这也是咱们这节课给出的建议【用来通过系统重新请求生成一个新的访问令牌】。

    “若access_token未超时,那么进行refresh_token有两种方式,(1)不改变access_token,但超时时间会刷新,相当于续期access_token(2)更新access_token的值,我们建议【统一更新access_token的值】”

    2020-07-05
    1
    1
  • Ryan Pan
    请问为什麽刷新令牌用过了一定要废除呢?
    有过期时间的话其实也可以用同一个来产生访问令牌不是吗?
    还有想问一般来说刷新令牌的期限会设多久呢?

    作者回复: 当刷新令牌被使用过,授权服务可以自行决定是否颁发新的刷新令牌来替换旧的,我们的建议是生成新的。

    refresh_token 的有效期具体多长时间,同样在OAuth 2.0 规范里面并没有给出确定值,一般比 access_token 的有效期长1-7天。

    2020-07-05
    1
  • AA
    淘宝的refresh_token也有过期时间,通过refresh_token刷新后,返回来assessToken和refresh_token,但refresh_token过期时间不会重新刷新,这是为什么要这样设置呢,当refresh_token为0时,是不是只能通过重新登录授权

    作者回复: 是的,当刷新令牌也过期了,只能重新登录再授权。

    2020-07-04
    1
    1
  • 树洞老人
    您好老师,我们一般如何验证第三方软件是否合法呢?

    作者回复: 第三方软件需要在平台一侧提前注册好app_id,同时平台会为三方软生成app_secret。

    2020-08-07
  • 请问下老师,用户登录第三方软件,用户的userid是存在哪里的,授权服务是如何user id的?

    作者回复: 如果是用微信登录这样的方式,我们讲它背后实际上是走了一次OAuth2.0的流程,第三方软件会拿到一个用户的标识,可以是类似”userid“的东西,这个第三方软件要存下来,用以判断当前的用户。如果是在这种方式下,授权服务就是指的微信内部的一个服务了,这个”userid“生成的粒度就是app粒度的,也就是不同的应用同一个用户会有不同的”userid“

    2020-08-06
  • Edison鹏
    有一点疑问:通过授权码获取到的用户token和用户主动登录获取到的token是同一个吗?如果不是同一个,那岂不是通过授权码获取到token之后 用户原来主动登录的token就失效了?但是根据历史经验来说并没有因为授权通过之后原来的应用需要重新登录啊。所以结论是 通过授权码获取到的用户token不会新生成?

    作者回复: 用户主动登录是授权的前提,因为授权的这个动作发生在平台一方,既然发生在平台一方,用户登录后,平台一方肯定是能获取到当前登录用户的信息,那么当授权服务去生成token的时候,就能够知道是哪个用户为哪个第三方软件进行了授权。严格意义上只有这一个给第三方软件生成的token。

    2020-08-04
  • DB聪
    关于“授权服务还需要将授权范围跟访问令牌 access_token 做绑定”这一步,我在比对上下文和代码的时候,有个疑惑想请王老师指点下。

    文中的这段代码,绑定了授权码“code”和授权范围“rscope”:
    Map<String,String[]> codeScopeMap = new HashMap<String, String[]>();
    codeScopeMap.put(code,rscope);//授权范围与授权码做绑定

    随后在“生成访问令牌 access_token 值”一步中,代码如下:
    String accessToken = generateAccessToken(appId,"USERTEST");//生成访问令牌access_token的值
    tokenScopeMap.put(accessToken,codeScopeMap.get(code));//授权范围与访问令牌绑定

    疑问:上述注释“授权范围与访问令牌绑定”,为何是codeScopeMap.get(code),而不是codeScopeMap.get(rscope)呢?我的理解是,codeScopeMap.get(code)指的是“授权码”,codeScopeMap.get(rscope)是“授权范围”。
    2020-08-04
  • 稻草人
    老师好,刷新令牌生成新的令牌,这个新生成的令牌有没有特定的规则,或者说算法,还是只是一个随机数,当我调用刷新令牌接口的时候是不是需要做一下权限的验证,不是谁都可以随便调用刷新令牌的接口的吧? 期待老师回复

    作者回复: OAuth 2.0 内部并没有规定我们令牌使用什么样的算法生成,我们可以是一个随机数,只要符合唯一性、不可猜测性就可以。在使用刷新令牌的时候,也是需要应用传递它的app_id和app_sercet的。

    2020-07-22
  • 稻草人
    老师好,refresh_token 令牌 获取新的令牌, 只需要调用刷新令牌接口就可以了么,不需要再次校验appkey和密钥了吗,不是谁都可以调的吧

    作者回复: 需要再次校验的。

    2020-07-22
  • 慎独明强
    音频时长20分钟,自己开了1.25倍速,再加上自己的整理笔记,加回答问题加看下方评论,一节课差不多要一个小时左右,再加上后面的温故知新
    2020-07-19
  • 慎独明强
    刷新令牌是有过期时间的,相当于是重新生成访问令牌的备份,过期时间应该一般和访问令牌的过期时间是一致的.相当于刷新令牌给访问令牌续期,那么在什么场景给访问令牌续期呢,比如说访问令牌的有效期为一天,超过一天就需要重新用户登录与授权.如果刷新令牌没有过期时间,感觉只要授权一次,就会一直有效了.那么安全性不是很好. 再想到自己生活中的app,淘宝可能是一个星期一个月,才需要重新输密码登录,银行的app,我退出去一次,就会需要重新登录.,上面两个例子是不是与OAuth没什么关系
    2020-07-19
  • Geek_6a58c7
    老师你好,有一个问题请教一下,授权码最终还是转成access_token并在网络中传输,这样从安全角度来说还是还是不安全的,这和授权服务直接返回access_token区别是什么,用授权码主要是解决什么问题呢?

    作者回复: OAuth 2.0 最初的场景就是发生在Web环境下,你可以看咱们的02课程里面,我们有提到。

    2020-07-14
  • piboye
    appsecret不应该是直接判断相等吧,appsecret不会出现在包中吧,他只是做hash验证吧

    作者回复: 可以直接判断,也可以将其作为【因子】加入到签名算法中。

    2020-07-14
  • 名:海东
    刷新令牌应该也是由过期时间的,不然可能存在安全问题。有个问题,需要请教老师,第三方软件(如小兔打单软件)注册到授权服务时是怎样的?它注册时有没有申请权限一说?应该没有用户(如小明)参与吧?第三方软件在用户授权时应该提前在授权服务做了注册。

    作者回复: 小兔打单软件应用对应的研发人员需要事先在授权服务一侧注册好,生成app_id和app_secret等信息,注册的时候就要申请一次权限,比如你这个应用是什么类型的,能访问哪些API,注册的时候没有小明的参与。

    2020-07-13
  • 唐朝农民
    String appStr = refreshTokenMap.get("refresh_token");
    if(!appStr.startsWith(appId+"|"+"USERTEST")){//该refresh_token值 不是颁发给该 第三方软件的
        return;
     }
    有一点不是很明白,授权服务是一个平台,不可能针对“小明”一个用户,那么在验证refresh_token时肯定不能硬编码成“USERTEST”,而是从上下文中获取的,请求这个用户ID 是 怎么传递的呢?

    作者回复: 在实际生产环境中,这个用户ID是不需要传递的也不可能被传递,因为OAuth 2.0的目的之一就是不让第三方软件接触到用户ID。

    第一次跟用户ID有关系的时候就是在用户给第三方软件授权的时候,这个时候如果用户没有登录就会先登录再授权,这一切都是发生在平台的一方,所以平台能够拿到用户的ID,继而在给第三方软件生成访问令牌的时候,就可以让这个访问令牌access_token的值跟第三方软件的app_id和用户ID做一个映射关系,同理refresh_token的生成也是一样的,并且refresh_token和access_token是一起生成并返回给第三方软件。

    我们在代码中为了演示refresh_token和access_token的生成都是在app_id和用户这个粒度的,是“特意”固定写死了一个USERTEST值。

    2020-07-12
  • hom
    请教下两个问题:
    1、不断用刷新令牌一直刷新,那token是不是可以无限延长?
    2、code在流程中被劫持了怎么办?

    作者回复: 1、刷新令牌也有有效期
    2、code在前端传输,还有在后端传输的app_secret

    2020-07-10
收起评论
38
返回
顶部