OAuth2.0-授权码模式

2023-11-19

解决问题

OAuth2.0授权码模式主要解决了信任问题:一个第三方网站需要访问我们Github上的数据(例如用户头像),那Github为什么要信任该网站?该对网站信任到什么程度?

  • 如果彻底信任该网站,那么将Github的用户名和密码直接交给该网站,由该网站直接登录即可。但这样使得该网站登录等同于用户登录,该网站将拥有与用户相同的权限,Github无法做权限的区分。
  • 如果不再授权给该网站,则需要更改Github密码,这样也会影响到其他被授权的网站。

基于此,如果可以为该网站提供一个专门的access_token,该access_token有专门的权限和过期时间,且Github可随时清除access_token的授权,这样问题就可以解决了。
为了提供这样一个access_token,使用如下思路:

  1. 向Github登记一下该第三方网站,Github会给出一个凭据。记下该凭据。
  2. 第三方网站提供了Github授权按钮,通常是在登录页面提供。
  3. 用户点击授权按钮来同意Github授权,则携带凭据跳转到Github的管理页面,此时需登录。若已经登录则执行步骤4。
  4. 登录Github后,验证凭据,同意授权,则生成一个access_token返回。
  5. 第三方网站保存该access_token并向Github请求数据。
  6. Github返回数据,第三方网站使用这些数据匹配已有账号,匹配成功则登录;否则创建新账号并关联,然后登录。

流程

以Github授权给第三方网站为例,OAuth2.0的授权码模式流程如下:
在这里插入图片描述
这里将第三方网站的Web端和服务端分开,而非合并在一起。Github也是。这样更容易理解整个流程的细节及设计原因。
要使用授权码访问到服务器上的资源,有三个阶段:

  1. 登记应用。
  2. 获取access_token
  3. 资源访问。

登记应用

假设我们是第三方网站的开发者,我们开发的网站要访问Github上的数据(例如用户头像),那Github为什么要信任我们的网站呢?
于是就需要进行应用的登记:我们明确地告知Github我们的应用的必要属性,Github登记后,就认可我们的网站了。
登记的流程为:
登录我们的Github账号,在其管理中找到Developer settings进入,在OAuth Apps下点击New OAuth App来创建一个新的应用。
新建应用时,需填入如下的属性:

  • Application name: 应用名。
  • Homepage URL:应用的首页地址。
  • Application description: 应用描述。
  • Authorization callback URL: 授权回调地址。默认地址。若授权请求中没有附带redirect_uri参数,则使用该地址。

点击Register application即可注册成功,Github会为该应用生成唯一的client_idclient_secret属性,这就是申请access_token的凭据。
然后第三方网站需要将client_idclient_secret保存下来,通常是作为整个网站的全局配置。该网站所有的用户都将共享这2个属性。

获取access_token

流程

第三方网站的Web端登录页需要提供一个使用Github账号登录的按钮。点击该按钮,Web端向自己的服务端索要client_idstate,拿到后Web端拼接出Github的授权页面地址,直接以外链形式打开该授权页面。
这个外链地址虽然是Github的,但需要写在我们的第三方网站前端页面中,以作为外链来跳转。同时还需要在外连上直接以明文形式附加参数,主要包含:

  • response_type: 模式类型。必须。授权码模式固定为code
  • client_id: 应用的id。必须。在Github登记后由Github生成,用于Github识别应用。
  • redirect_uri: 重定向地址。可选。无论是否同意授权,Github都要调用该外链地址来跳转回第三方网站。如果不附带该参数,则Github会使用在注册应用时提交的Authorization callback URL
  • scope: 权限。可选。用于说明请求资源的范围,即Github允许第三方网站访问哪些资源。通常scope参数依赖于授权方的定义,这里是依赖Github的定义。
  • state: 校验码。可选。当Github调用重定向地址时会再次传回该参数,用于第三方网站对请求进行合法校验,从而防止CSRF攻击。因此第三方网站需要将state保存在本地,以用于后续的校验。

外链到Github的页面打开后,访问的就已经是Github的Web端了,若Github没有登录则会提示登录Github账号。登录后,需要在页面上点击[确认授权]按钮。
点击后,Github的Web端向Github的服务端发确认授权请求,服务端生成授权码code返回给Web端。然后Web端会将code和跳转页面时传入的state拼接到redirect_uri后,以https的外链形式在浏览器中进行跳转,这样浏览器页面就又跳转回第三方网站(跳回第三方网站是在回传code时)。
浏览器页面跳转后,第三方网站的Web端将codestate发给自己的服务端,服务端对state进行校验,确认是自己发出的。
然后第三方网站的服务端向Github的服务端发送申请access_token的请求。参数主要包含:

  • client_id: 应用的id。必须。登记时Github生成。
  • client_secret: 应用的秘钥。必须。登记时Github生成。
  • grant_type: 授权方式。必须。当前为授权码方式,传入code
  • code: 上一步Github发来的授权码。必须。
  • redirect_uri: 必须。用于校验与请求code时传入的redirect_uri是否一致,不是用来做页面重定向的

Github校验client_id+client_secretredirect_uri+code无误后,生成access_token,直接放入请求的Response中返回给第三方网站的服务端。为了处理access_token过期问题,通常还会一起返回一个refresh_token
第三方网站的服务端收到返回,取出access_token后,即可调用Github的接口来获取用户相关的信息。获取到信息后,首先判断是否已存在关联账户,若存在则直接登录;否则使用这些信息来创建新用户,然后登录。
由于授权码code是跟Github的具体用户相关的,因此生成的access_token也是跟用户相关的,多个用户的access_token不同。

为什么要借助授权码code来获取access_token

第三方网站发出第一次请求时获取到了一个授权码code,使用授权码code再次获取access_token,然后才使用access_token来获取用户信息。为何要加入一个授权码code,而不是直接第一次请求就返回access_token呢?
从上述流程分析,可知:

  • 第一次请求时需要用户点击Github的[确认授权]按钮,因此页面必须跳转到Github网站的Web页面。由于需要用户点击操作,就无法将结果直接放在Response中返回,因为用户可以等一会再点授权按钮,这个等待时间可长可短,放在Response中很可能用户还没点按钮就请求超时了。
  • 跳转到了Github的Web页面,授权后必须再跳回第三方网站的Web页面,这样就需要从Github的Web页面构造一个第三方网站的Web页地址以外链形式打开,同时将授权结果拼接到URL参数中,这意味着授权结果是暴露在公网上的。若直接返回access_token拼接在URL中显然会造成安全问题。
  • 生成access_token需要校验client_secret,但client_secret是个需要保密的值,直接以外链形式传输该属性会直接暴露在公网上,同样有安全问题。

综上,先通过client_id获取一个跟Github的具体用户相关的授权码code,然后由第三方网站的服务端使用client_id+client_secretredirect_uri+code这4个属性来请求Github获取access_token。由于获取的请求交给了服务端,也就不用再担心client_secretaccess_token暴露的问题。
某些网站为了更加安全,对code设置了有效期,例如5分钟内有效,且只能使用一次。
实际上,OAuth2.0的简化模式就是取消掉了code这一步,直接在第一次请求时的重定向地址中附加access_token 由于存在暴露风险,因此往往只用于安全性不高的场景,且另外有效期非常短。通常也不会发放refresh_token

资源访问

授权码模式用于Github授权账号登录到第三方网站。因此第三方网站拿到Github账号的信息后使用这些信息来创建新用户即完成了对Github必要的资源访问,只需要访问一次,不需要重复访问。
当然,第三方网站可以对access_token与新创建的账号进行绑定存储,并使用refresh_token进行有效期刷新,从而也可以重复地对Github进行资源访问。
但一般来说,这些访问请求都是由第三方网站的后端负责,第三方网站的前端是不接触access_token的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OAuth2.0-授权码模式 的相关文章

随机推荐

  • android图像识别(百度普通物体识别)

    android图像识别 采用百度sdk 识别准确率基本上能用 主要缺陷是百度sdk免费额度有限 demo链接如下 仅供参考https download csdn net download android xc 12274161
  • Python进阶之CrawlSpider的应用及Scrapy配置项的引用

    1 CrawlSpider的应用 CrawlSpider可以根据规则自动分析链接的数据并按照正则的要求取出需要的数据 scrajpy startproject yg cd yg 注意 t crawl参数 scrapy genspider t
  • 解决SqlServer批量插入最多2100条数据的方法

    SqlServer批量插入数据时最多不能超过2100条 记录一下解决办法 Java代码 public void batchInsert List
  • 基于vue实现移动端点击上方导航,内容滑动切换,滑动内容导航自动切换。

    这是在日常开发过程中常见的选项卡 带滑动切换效果 小白一枚 不足之处还望体谅 包涵 这也是第一次尝试写博客 以后会继续分享一些工作中的问题与收获 实现效果 点击上方导航 当前导航添加样式 下方内容滑动切换 滑动下方内容上面导航切换 第一步
  • 论文笔记:Region Representation Learning via Mobility Flow

    2017 CIKM 1 摘要和介绍 使用出租车出行数据学习区域向量表征 同时考虑时间动态和多跳位置转换 gt 通过flow graph和spatial graph学习表征 出租车交通流可以作为区域相似度的一种 A区域和B区域之间流量大 gt
  • JS 变量提升和函数提升

    变量提升 这里介绍一个变量提升提升的经典案例 for var i 0 i lt 10 i setTimeout gt console log i 1000 这里打印是10个10 因为在执行第一个setTimeout时 Js不会等待1秒后再去
  • 怎么解决“无法打开包括文件:“graphics.h”: No such file or directory”的问题

    在接手同伴的中国象棋项目时 导入项目后 发现VS一直提示 无法打开包括文件 graphics h No such file or directory 在查阅资料后发现是缺少easyx文件 接下来 就介绍一下手动配置一下easyx文件 eas
  • 特殊类型动归--区间动归与环形动归

    区间动归 某类有序事件中前若干个事件的子答案 不能再支撑状态转移 我们需要去寻找 从某个元素起到另一个元素结束所包含所有的 连续 元素的子答案 作为状态 可以想象 在这个描述下 每个状态会对应于原题序列上的一个区间 区间具有良好的性质 短的
  • 深度学习(1):BP神经网络实现银行客户流失预测

    目的 针对银行客户行为和统计数据实现客户流失预测任务 一 数据准备 1 数据集 select data csv 作为训练样本 数据预处理方式 归一化 数值化 CreditScore 信用分数 EB 存贷款情况 EstimatedSalary
  • centos 建立回收站

    linux下的回收站在每一个当前用户目录 local share Trash中 也可以给linux添加一个回收站 mkdir tmp trash tmp 建立一个回收站目录 vi bin trash 编辑一个文件 mv tmp trash
  • python之浅拷贝、深拷贝

    什么是浅拷贝 深拷贝 理论来自python基础教程 在 Python 中 对象赋值实际上是对象的引用 当创建一个对象 然后把它赋给另一个变量的时候 Python 并没有拷贝这个对象 而只是拷贝了这个对象的引用 我们称之为浅拷贝 在 Pyth
  • 腾讯云 Finops Crane 开发者集训营 - 云原生如何助力企业搞定成本优化

    引言 随着docker的技术普及 越来越多的企业加入了云计算发展进程 云原生产业发展迅猛 云原生建设投入比例明显 面对大规模的集群投入 部署 维护等问题也逐渐产生 越来越多的企业对云原生不断提出更高要求 同时云原生技术简化运维的效能提 升开
  • .Net WebAPI 高速下载文件接口实现

    接触WebAPI一年多了 感觉是个承上启下 开创未来的技术 老一辈程序员写接口就像写方法一样 不需要了解太多网页的知识 却可以在浏览器中访问这些接口 由于是基于HTTP协议 因此不管是PC 手机还是嵌入式均可顺利访问 对于当下软件多终端的设
  • Spark 【分区与并行度】

    RDD 并行度和分区 SparkConf setMaster local 我们在创建 SparkContext 对象时通常会指定 SparkConf 参数 它包含了我们运行时的配置信息 如果我们的 setMaster 中的参数是 local
  • 服务器维护中轩辕,轩辕服务器为什么老是-轩辕服务器为什么 – 手机爱问

    网三轩辕为什么上不去了啊 网三轩 朋友 我先问下 有以下的情况吗 第一 你的号上去后 选线的时候是不是请重从连接 要是的话这是卡号了 第二 你上号的时候 写账号和密码 就提事说 从请从新登陆 这不是卡号 这也是卡线了 这是你卡线的时候总来回
  • xray扫描器的使用 (长亭科技公司创造)

    简介 xray是一款可以使用HTTP HTTPS代理进行被动扫描的安全工具 支持功能如下 独立的 URL 扫描 基于 HTTP 的被动代理扫描 同时支持HTTPS SQL注入检测模块 命令注入检测模块 任意重定向检测模块 路径遍历模块 Xr
  • c# Newtonsoft.Json 常用方法总结

    1 实体类的 Json 序列化和反序列化 我们以如下的 Person 类举例 其中包含了常用的数据类型 public class Person public int ID get set public string Name get set
  • Kubernetes之kubectl命令详解及常用示例

    文章目录 一 kubectl语法 二 子命令详解 1 command 2 type 3 flags 4 kubectl的输出格式 三 kubectl常用命令 1 查看类命令 2 操作类命令 3 其他操作 一 kubectl语法 kubect
  • 容器与云的碰撞——一次对MinIO的测试

    事先声明 本次测试过程完全处于本地或授权环境 仅供学习与参考 不存在未授权测试过程 本文提到的漏洞 MinIO未授权SSRF漏洞 CVE 2021 21287 已经修复 也请读者勿使用该漏洞进行未授权测试 否则作者不承担任何责任 随着工作和
  • OAuth2.0-授权码模式

    解决问题 OAuth2 0授权码模式主要解决了信任问题 一个第三方网站需要访问我们Github上的数据 例如用户头像 那Github为什么要信任该网站 该对网站信任到什么程度 如果彻底信任该网站 那么将Github的用户名和密码直接交给该网