OAuth1.0介绍

背景

为什么需要OAuth授权呢?

最典型的应用场景就是第三方登录了, 我们开发了一个网站希望用户可以QQ登录, 但是怎么能拿到用户的 QQ 信息呢? 用户将 账号密码告诉我们当然可以, 但是这样有如下隐患:

  • 我们拿到了用户的密码, 这样很不安全. 而且任意一个应用被黑, 所有相关站点均受影响
  • QQ 需要支持密码登录, 但是单纯密码登录并不安全. 因此进而影响 QQ 的安全问题
  • 我们拿到密码之后, 就相当于拥有了用户的所有信息, 这样无法进行权限限制
    • 可能只是希望授权用户名和头像, 但是连着好友列表一起交代出去了
  • 用户一旦修改密码, 所有之前授权过的应用全部失效

基于以上原因, 就需要有这样一套机制:

  • 不基于密码的授权
  • 授权存在时间限制, 并且随时可以收回权限
  • 收回单个应用的权限, 不会对其他已授权的应用造成任何影响
  • 可以仅授予个别权限, 而不是所有

没错, OAuth就是为了解决这个问题而提出来的.

介绍

OAuth是什么呢? 在RFC 文档中是这样介绍的.

OAuth provides a method for clients to access server resources on behalf of a resource owner (such as a different client or an end- user). It also provides a process for end-users to authorize third- party access to their server resources without sharing their credentials (typically, a username and password pair), using user- agent redirections.

写的比较官方哈, 简单说, 就是授权他人以拥有临时访问资源的权限.

那么, OAuth1.0是如何实现这样的机制呢?

实现

在介绍其实现之前, 需要先来了解OAuth中的几个概念.

  • 角色
    • Consumer 消费者, 既需要访问资源的应用
    • ServiceProvider 服务提供者, 既提供资源的服务器
    • User 用户

依旧使用我们上面的例子, 我们的博客网站需要接入 QQ 登录. 在这里, 博客网站就是其中的Consumer, 而 QQ 服务器就是ServiceProvider了. 为了方便立即, 下面均称为 博客网站 QQ服务器. 我们获取授权的流程大致如下图:

image-20220218204953974

对其中的各个流程进行介绍

流程

在请求之前, 博客网站需要到 QQ 服务器 进行注册, 并获得如下标识:

  • consumer_key: 网站标识符
  • consumer_secret: 网站使用的私钥

1. 获取 request_token

网站向QQ 服务器申请一个临时凭据, 用来在本次授权过程中进行校验.

携带参数

  • oauth_consumer_key
  • oauth_signature_method: 签名使用的生成方法
  • oauth_signature: 本次请求的签名, 使用consumer_secret生成
  • oauth_timestamp 时间戳, 用于对本次请求进行校验
  • oauth_callback 回调链接, 用于在用户授权之后回调通知消费者
  • oauth_nonce 随机字符串
    • 此参数用来防止重放攻击, 即别人拿到请求链接再次请求
    • 因此, 服务提供者会对其进行验证是否处理过

返回数据

  • request_token: 此 token 仅用作后面授权中校验使用, 以及对本次授权进行标识
  • request_secret: 用于本次授权的后续请求进行加密, 使用在第5步

2. 重定向到服务器授权页面

将页面重定向到 QQ 服务器 的授权页面.

携带参数

  • request_token: 用来向 QQ 服务器标识本次授权

3. 用户在 QQ 服务器完成授权操作

用户在 QQ 服务器的授权页面进行登录并授权

4. 回调函数通知授权成功

用户授权成功后, QQ 服务器将链接重定向到 第一步指定的 回调链接. 并在回调链接上附带结果:

  • request_token: 用来对本次授权进行标识. 毕竟博客网站收到回调时, 需要知道是哪个用户授权成功了.
  • verifier: 在下一步获取 access_token 中检验使用. 具体作用在下一步说明.

5. 授权成功后获取 access_token + access_secret

此时用户已经同意了权限的授予, 博客网站可以到 QQ 服务器获取用户的授权码了.

返回数据

  • access_token
  • access_token_secret

用户后续就使用这两个授权信息到 QQ 服务器请求资源.

access_token_secret作用

这里有个小疑问, 既然有了access_token, 又为什么需要access_token_secret呢?

因为访问数据使用HTTP协议, 对数据的传输过程没有安全保障. 在后续访问资源时, 若仅使用consumer_secret对请求进行签名, 若consumer_secret泄露了, 那么攻击者只要获得用户的access_token就拥有了其权限. 而access_token又需要在访问是携带在参数中对权限进行标识. 故而十分危险.

在生成签名时, 额外加上access_token_secret进行签名, 而access_token_secret不会在后续访问中传递, 每个用户又都是不同的, 因此即使consumer_secret泄露了, 攻击者也无法获得所有用户的权限.

携带参数

  • consumer_key
  • request_token
  • signature_method
  • timestamp
  • nonce
  • verifier
  • signature

verifier作用

那么, 这里的oauth_verifier有必要么? 其实它是为了防止 session固话攻击, 感兴趣的可以搜索"OAuth Session Fixation Attack"查看具体内容. 这里简单介绍一下.

假设, 有一个攻击者监控了你的网络请求, 因为使用了HTTP协议, 明文信息也没什么秘密. 那么攻击者就可以在第一步时获得本次授权的request_token. 同时攻击者又通过暴力破解或其他方法, 获得了consumer_secret.

此时, 若没有verifier参数, 本次请求的所有参数攻击者均可以构造. 若攻击者频繁访问本次请求, 又恰好在用户授权完成和网站回调的间隙发起了合法访问, 就会成功获得用户的access_token.

通过添加随机的verifier可以使得本次请求不可预测.

问题

对于OAuth1.0实现的一些问题:

  • 使用了HTTP协议, 安全性较低
  • 使用HTTP协议, 没有对服务提供者的真实性进行校验
  • 对非web应用(如安卓)支持很不友好. (也有通过 PIN 码实现的, 这里不展开介绍了)
  • 签名过程复杂. 需要同时使用consumer_secret+access_token_secret进行签名. (也是因为使用HTTP协议)

这些问题在OAuth2.0得到了解决, 详情查看下一篇文章: OAuth2.0介绍

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/508356.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PHP 数组的内部实现

前言 这几天在翻github的时候, 碰巧看到了php的源码, 就 down 下来随便翻了翻. 地址: https://github.com/php/php-src 那么PHP中什么玩意最引人注目嘞? 一定是数组了, PHP中的数组太强大了, 于是就想着不如进去看看数组的实现部分. 这篇文章打算全程针对代码进行解读了. 以…

go1.18新特性

前言 最近突然发现golang更新版本1.18了, 于是迫不及待的来看看这个版本加了些什么新特性. 没准就有之前困扰很久的问题, 在新版本被官方解决了呢. 先简单概述一下都有些什么变化, 后面再细说: 增加泛型的支持系统库方法增加修复 bug 另外, 像"系统内核更新"这种…

base64编码原理

引出 众所周知, ASICC编码共127个, 使用了7个bit进行编码. 而文件在存储的时候是以 字节为单位, 也就是8bit. 这就难免导致有一部分编码是没有定义在ASICC编码中的. 而在网络中传输二进制数据的时候(字符串本质上也是二进制数据嘛), 如果直接传输比特流, 倒也不是不可以, 只是…

页面加载速度-合并资源文件

前言 一直觉得自己的博客站点页面加载很慢, 就想着去优化一下. 呐, 下图是一次文章页面的加载, 需要2.5s. 其中 js 文件就有18个. 众所周知, 浏览器对资源文件的并行下载数量是有限制的(不同浏览器限制不同). 也就是说, 这18个 js 文件是无法同时下载的, 再说了, 页面中还有其…

hbase/thrift/go连接失败

问题 在通过Go连接hbase的过程中, 发现 get操作可以查到数据, 但是scanner命令访问数据失败, 也没有报错, 就是单纯的查不到数据. 而且Python PHP都一切正常. 这里简单复述一下我出现问题的情况, 安装过程和网上大部分内容一致, 这里简单列一下, 只是为了查询问题时参考安装过…

常用搜索引擎及语法

在平常需要进行搜索的时候是不是只知道Google Baidu ?? 他们其实是全文搜索引擎, 还有一些特定领域的搜索引擎. 而且, 搜索时可以添加特定语法, 让你的搜索事半功倍. 本文整理各种场景下使用的搜索引擎, 以及各个搜索引擎支持的语法, 不定期进行更新. 如果你知道其他搜索引…

自旋锁与互斥锁

前言 在编程中经常需要使用到互斥. 互斥就是, 这个事情只能有一个人干, 我正在做着的时候, 别人要想做这件事就得等我做完了. 互斥的实现是通过锁的机制, 也就是我把这块锁上了, 别人就进不来了, 等我做完再把锁释放掉. 但是, 前辈们已经证明了, 要想单纯的在软件层面上实现…

printf缓冲区踩坑

问题 碰到了这样一段代码(经过简化的): #include "stdio.h" #include "unistd.h" #include "sys/wait.h"int main(){fork();printf("1\n");fork();printf("1\n");wait(NULL);return 0; }这里我们简单算一下, 结果会打印几…

进程切换时是如何保存上下文的

前言 当前操作系统大部分采用分时的进程调度, 既每个进程运行一小段时间, 然后切换到下一个进程运行, 依次往复. 当进程运行的时候是独占CPU的, 此时操作系统是无法强行介入的, 为了将执行权让出来, 就需要硬件的配合了. 硬件每个一个时钟周期(比如10ms), 就会产生一个时钟中…

GO/testing包

前言 之前在写GO单元测试的时候, 使用了这个结构testing.T. 进来无事翻了翻, 发现testing包中还有一些其他的结构体, 想来是不同用处. 没想到GO的testing包竟然默默做了这么多支持, 之前竟然不知道. 在testing包中包含一下结构体: testing.T: 这就是我们平常使用的单元测试t…

CPU的分支预测

前言 最近在进行性能调优的时候, 碰到了这样的一段代码(为了展示问题而简化的代码): <?php // 第一次运行 $start microtime(true); for ($i 0; $i < 100; $i) {for ($j 0; $j <1000; $j) {for ($k 0;$k < 10000; $k) {}} } $end microtime(true); echo fi…

Golang Context 简介

前言 在写Golang程序调用各种第三方库的时候, 经常会传一个叫做Context的参数. 之前基本上见到接Context, 根本不管是干什么用的, 直接无脑context.Background(). 但是, 传着传着就不免发生一些小疑问, 这个参数到底是干什么用的呢? 这么多库都在使用, 至少说明其是Golang中…

PHP获取Opcode及C源码

是什么 在开始之前, 必须要先介绍一下Opcode是什么. 众所周知, Java在执行的时候, 会将.java后缀的文件预先编译为.class字节码文件, JVM加载字节码文件进行解释执行. 而字节码文件存在的意义, 就是为了加速执行. 那么PHP的Opcode与之类似, 也是从.php文件到执行的过程中, 所…

PHP require/include 区别

前言 在PHP中, 载入文件可以选择使用require, 也可以使用include, 那么那他们有什么区别呢? 看了网上的一些文章, 说他们使用场景不同, require一般在文件开头引入文件, include一般在函数中动态引入文件. 但是我觉得并不是这么简单, require是作为语言结构(关键字)出现的, …

RESTful API规范

前言 我现在工作的公司是在毕业前实习的公司, 实习结束后直接转正, 因此也是我任职过的唯一一家公司. 在日常工作进行 HTTP 接口的开发时, 发现了一个疑惑, 只用到了POST和GET请求, 但我们知道 HTTP还有PUT/DELETE等等, 为什么不用呢? 并且, 接口的响应码也只有200, 接口是…

Golang 接口原理

问题 小提示, 若想直接查看原理, 可从接口原理开始查看. 有这样一段GO代码: func main() {var obj interface{}fmt.Printf("obj nil. %b\n", obj nil)type st struct{}var s *stobj sfmt.Printf("s nil. %b\n", s nil)fmt.Printf("obj nil. …

Docker kill 1无效

前言 我们在平常强制停用一个进程的时候, 会选择什么命令? 一般在测试使, 不考虑程序突然中断带来的影响, 直接使用kill -9 pid强制停止就行. 但是, 就在刚刚, 我启动了一个docker容器, 进入容器后执行命令kill -9 1没有任何效果??? 啊这, 为什么呀? 尝试 为了解释这个…

容器内存相关知识

这篇文章是我研究容器内存整理出的相关内容. 前后内容并没有上下文关系, 每个知识点都可以单独查看. 内存控制 使用这样的命令启动一个容器docker run -d -m 300M xxx. 可以限制容器使用的内存最大为300M. 那么docker是如何实现容器的内存限制呢? 其实是操作系统已经做好了…

三星识别文字_比亚迪电子助力三星Galaxy Note 10系列霸气首发!

三星有子初长成气宇轩昂 秀美俊逸减之一分则嫌柔增之一分则嫌赘2019年8月7日于纽约巴克莱发布Galaxy Note 10系列用简约 重构美三星Galaxy Note 10与Galaxy Note 10分别搭载了6.3英寸和6.8英寸的超感官全视曲面屏&#xff0c;均采用单摄挖孔屏&#xff0c;开孔位于屏幕正上方。…

lisp 设计盘形齿轮铣刀_机械设计基础——周转轮系传动比的计算

点击上方蓝色字体&#xff0c;关注我们15(视频来源于网络&#xff0c;仅供学习交流&#xff0c;侵权请联系删除)机械计重点学习指导机械原理全书重点提要轴的结构改错机械设计作业集01机械设计作业集02机械设计作业集答案机械原理作业集机械原理作业集答案轴的强度计算院校推荐…