首页 > 其他分享 >OAuth2.0授权码模式详解

OAuth2.0授权码模式详解

时间:2024-09-01 16:26:28浏览次数:10  
标签:微信 用户 开放平台 access token 详解 授权 OAuth2.0

OAuth 2.0一词中的"Auth"表示"授权Authorization",字母"O"表示"开放Open",连在一起就表示"开放授权"。这也是为什么我们使用OAuth的场景,通常发生在开放平台的环境下。

OAuth 2.0提供了4种模式:

资源拥有者凭据许可(Resource Owner Password Credentials)
隐式许可(Implicit)
客户端凭据许可(Client Credentials)
授权码许可(Authorization Code)
本文将介绍OAuth2.0授权码许可的模式,授权码许可是应用最为广泛的开放授权模式,比如微信开放平台、阿里开放平台等都是基于这个模式做开放授权。

开放授权出现的意义
我们首先需要区分下认证和授权:

认证(Authentication):用来验证某个用户是否具有访问系统的权限。如果认证通过,该用户就可以访问系统,从而创建、修改、删除、查询平台支持的资源。认证的方式就是我们登录,比如账密登录、手机验证码登录等。
授权(Authorization):用来验证某个用户是否具有访问某个资源的权限,如果授权通过,该用户就能对资源做增删改查等操作。
简单而言,认证就是证明访问者的身份,决定他是否能进入系统;授权则是决定访问者能做哪些内容。一般来说,都是先认证后检查授权。

OAuth 诞生之初是为了解决 Web 浏览器场景下的授权问题。比如有一个网站A,在新用户注册时是支持QQ账号注册的,如果网站A能拿到QQ昵称和头像作为网站A用户注册的基本资料,这样新注册用户流程就简单多了,很多信息都不需要用户自己填写,直接套用QQ号的信息就可以了。这样的注册模式就对用户很友好,自然很容易提升用户注册的热情。

这个【访问用户QQ头像和昵称】就涉及到授权问题了。我的QQ信息为什么可以给网站A使用?如果我同意网站A获取我的QQ昵称,那我的QQ空间的信息网站A是否也可以访问呢?这就涉及到授权范围的内容了。开放授权是个很复杂的模式,需要一个安全且友好的机制来支持。

注册时的开放授权和长期访问QQ空间信息的开发授权的复杂度时不一样的。

注册时授权获取QQ昵称等信息是一次性的,需要考虑的事情可能没那么多,也许一个请求回复就能拿到这些信息了,以后不会再需要二次获取。但如果网站A还有个业务,支持管理QQ空间里的照片,此时需要向用户申请授权:请允许网站A可以访问你的QQ空间的照片。这种资源的访问就不是一次性了,是反复多次的访问,这个就更为复杂,首先我们不可能网站A每一次访问我们都点一次【同意授权】,如果我们当时没有登陆QQ,还得先账密登录QQ才可以进行授权。这样对用户体验很不友好。因此需要一种安全便捷的方式去处理这种频繁访问受限资源的场景。这个就是开放授权出现的意义:把私有资源有限地开放给第三方访问和使用,而且需要做到安全高效。OAuth 2.0能很好地解决了这个问题。

OAuth2.0 定义的角色类型
根据 OAuth 2.0 协议规范,OAuth 2.0体系下有四个角色类型:

授权服务器,负责颁发 Access Token,比如微信开放平台授权服务器。
资源所有者,你的应用的用户是资源的所有者,授权其他人访问他的资源。比如微信用户是资源所有者。
调用方,调用方请求获取 Access Token,经过用户授权后,微信开放平台为其颁发 Access Token。调用方可以携带 Access Token 到资源服务器访问用户的资源。比如调用方是上文说的网站A。
资源服务器,接受 Access Token,然后验证它的被赋予的权限项目,最后返回资源。比如微信开放平台资源服务器。
接下来,我们将以微信用户授权第三方网站A的案例,介绍OAuth2.0授权码模式下的授权流程。

OAuth2.0授权码模式流程
我们先看下业界标杆微信开放平台是怎么做开放授权的。网站应用微信登录是基于OAuth2.0协议标准构建的微信OAuth2.0授权登录系统,微信OAuth2.0授权登录目前支持authorization_code模式。

先上序列图:

流程步骤:

网站A需要在微信开放平台注册,填写回调地址,并获得相应的 AppID 和AppSecret。
用户登录了网站A,获得了网站A的登录态,这里用JWT来维护登录态。
此时网站A需要访问用户的微信相关资源,这里需要获得用户的微信授权。网站A弹出一个页面引导用户去微信开放平台的网站来授权。
用户点击【去授权】,浏览器跳转到微信二维码界面。
此时微信用户尚未在web端登录,因此需要微信用户【扫码登录】,登录成功后浏览器带着AppID请求微信开放平台,请求授权给网站A。
微信开放平台同意后返回页面让微信用户确认:网站A将获取以下权限:1. ... 2. ...,是否同意授权。
点击【同意授权】,用户浏览器就带着AppID和重定向URI两个参数去请求微信开放平台的授权服务器。重定向URI是网站A的地址。
微信开放平台的授权服务器收到请求,通过AppID知道了这个是要微信用户要给网站A授权,因此生成了一个授权码CODE,以重定向的方式返回给微信用户,重定向的地址填的是第7步请求带上来的URI,并参数带上这个CODE。
微信用户收到重定向的回复后,拿出重定向URI和CODE,重定向跳转到这个URI,并参数带上这个CODE。因为跳转的网址是网站A的域名地址,因为用户已经在该网站登录了,因此这个请求会带上登录态的JWT。
网站A收到微信用户CODE后,从JWT中解析出这个请求的来源用户的uid,这样网站用户uid就跟CODE有了绑定关系。接着拿出自己的AppID 和AppSecret,跟CODE一起请求微信开放平台授权服务器。
微信开放平台授权服务器收到AppID + AppSecre + CODE 三个参数后,生成access_token、refresh_token,返回这些token给网站A。
网站A拿到access_token后就存储起来,有了uid->access_token的映射关系。后续带着这个access_token就可以访问微信用户的指定资源了,无需每次要微信用户登录和授权。
access_token和refresh_token的关系
access_token是调用授权关系接口的调用凭证,由于access_token有效期(目前为2个小时)较短,当access_token超时后,可以使用refresh_token进行刷新,access_token刷新结果有两种:

若access_token已超时,那么进行refresh_token会获取一个新的access_token,新的超时时间;
若access_token未超时,那么进行refresh_token不会改变access_token,但超时时间会刷新,相当于续期access_token(注意,微信开放平台是在原来的access_token上做延时,有的开放平台是直接换一个新的access_token)。

refresh_token拥有较长的有效期(30天),当refresh_token失效后,需要用户重新授权。

因为access_token是需要频繁在网络上传输的,因此被窃取的风险大,所access_token的有效时间设置较短;refresh_token仅仅在续签access_token时会在网络上传输,被窃取的风险相对小点,因此refresh_token拥有较长的有效期。这样一长一短的双token机制会比较安全。

双Token机制更为安全,而且可以很好的处理在线、离线续签的问题,可以参考这个回答深入理解双Token机制。

jwt续签为什么要使用双token,没看明白啊,感觉单个token也可以啊? https://www.zhihu.com/question/506320859/answer/2913798899
47 赞同 · 19 评论回答
OAuth2.0授权码模式困惑点
为什么OAuth2里面在获取access token之前一定要先获取code,然后再用code去获取access token?

为什么OAuth2里面在获取access token之前一定要先获取code,然后再用code去获取access token? https://www.zhihu.com/question/27446826/answer/2916005175
15 赞同 · 2 评论回答

Token的续签是系统自动完成的吗?

续签是客户端写代码来实现自动更换的,比如客户端本地周期检查access_token是否即将过期或者已经过期,是的话就拿refresh_token去换新的access_token。

授权码被盗取后,人家不能也模拟服务器请求获取access_token吗?

首先授权码有以下基本的安全措施:授权码存在有效期,一般很短只有几分钟,过期了就没法用了;授权码只有一次使用机会,如果该授权码已经被人兑换过了,后面就没法兑换了。

如果是无appSecret的模式,授权码被盗取后是有机会被模拟盗窃access_token的。

在appSecret这种模式下,兑换access token,如果只有授权码是没法兑换access token,还得有appSecret+授权码来兑换。所以appSecret这种模式更为安全。

redirect_uri既然在注册的时候已经填了,为什么请求授权码时还要再传一遍这个参数?

因为注册时可能会填了多个uri,因此带参数redirect_uri请求时,授权服务器会校验是否该uri是否处于注册的uri列表中。

参考链接:https://zhuanlan.zhihu.com/p/610490265?s_r=0

标签:微信,用户,开放平台,access,token,详解,授权,OAuth2.0
From: https://www.cnblogs.com/leifonlyone/p/18391399

相关文章

  • 【Linux系列】du命令详解
    ......
  • 0Ω电阻详解
    0Ω电阻详解0Ω电阻,请不要小瞧它0欧姆电阻即电阻标值为0欧姆的电阻,多用于PCB设计等方面,是一种理想电阻。那0欧姆电阻是表示没有电阻吗?当然不是,0欧姆电阻的阻值不是0欧姆,只是接近0欧姆。如下图分别是0欧姆贴片电阻和色环电阻的样式。0Ω电阻的作用调试方便或者兼容设计:可以选......
  • STM32的寄存器详解
    目录前言一、 STM32单片机寄存器概述1.寄存器的作用2.寄存器的分类二、STM32内核寄存器1.程序计数器(PC)2.堆栈指针(SP)3.链接寄存器(LR)4.控制寄存器(CONTROL)三、STM32外设寄存器1.GPIO寄存器2.USART寄存器3.TIM定时器寄存器4.ADC寄存器四、寄存器的访问方式......
  • 双指针算法详解
      我的主页:2的n次方_       1.双指针算法双指针算法是一种在数组或字符串中常用且高效的算法技术,它通过维护两个指针(或索引)来遍历数据结构,从而解决某些问题。这种算法能够减少不必要的重复遍历,降低时间复杂度,并且往往能够使得代码更加简洁易懂。根据指针......
  • IoC&AOP详解
    1.IoC1.1什么是IoC    IoC即控制反转/反转控制。它是一种思想而不是一种技术实现,描述的是:Java开发领域对象的创建以及管理的问题    例如:现有类A依赖类B        传统开发方式:在类A中通过new关键字来创建一个类B的对象      ......
  • MVCC详解
    1.概念1.1什么是MVCCMVCC,全称Multi-VersionConcurrencyControl,即多版本并发控制。MVCC是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,在编程语言中实现事务内存。MVCC在MySQLInnoDB中的实现主要是为了提高数据库并发性能,用更好的方式去处理读-......
  • 集合及数据结构第十二节(上)———— 二叉搜索树和Map、Set详解
    系列文章目录集合及数据结构第十二节(上)————二叉搜索树和Map、Set详解二叉搜索树和Map、Set详解搜索树的概念二叉搜索树的实现性能分析和java类集的关系搜索的概念及场景模型关于Map的说明关于Map.Entry<K,V>的说明Map的常用方法说明TreeMap的使用案例Set的常见......
  • Python的Matplotlib库详解
    Python的Matplotlib库详解Matplotlib是Python中功能强大的数据可视化库,广泛应用于科研、数据分析、报告生成等领域。它能创建各种类型的图表,帮助用户直观地展示数据。一、使用场景1.数据探索和分析:在数据科学领域,Matplotlib经常被用来绘制各种图表,如折线图、散点图、......
  • c语言分支与循环详解
    使用if、switch实现分支结构,使用for、while、dowhile实现循环结构分支:1.1if语句的语法if(表达式) 语句;在c语言中0表示假,则语句不执行。非0表示真,语句执行1.2else与if对应,比如说一个数不是奇数就是偶数了if(表达式) 语句1;else 语句2;表达式成立则执行语句1,不成......
  • 【Material-UI】Text Field中的 Performance 优化详解
    文章目录一、TextField组件概述1.组件介绍2.性能挑战二、全局样式注入行为的优化1.问题的根源2.禁用全局样式注入3.自定义全局样式三、实际场景中的性能优化应用1.大规模表单中的优化2.动态表单生成中的优化3.提升用户体验四、最佳实践与注意事项1.谨慎使......