Day978.如何在移动App中使用OAuth 2.0? -OAuth 2.0

如何在移动App中使用OAuth 2.0?

Hi,我是阿昌,今天学习记录的是关于如何在移动App中使用OAuth 2.0?的内容。

除了 Web 应用外,现实环境中还有非常多的移动 App

那么,在移动 App 中,能不能使用 OAuth 2.0 ,又该如何使用 OAuth 2.0 呢?

没错,OAuth 2.0 最初的应用场景确实是 Web 应用,但是它的伟大之处就在于,它把自己的核心协议定位成了一个框架而不是单个的协议。这样做的好处是,可以基于这个基本的框架协议,在一些特定的领域进行扩展。

因此,到了桌面或者移动的场景下,OAuth 2.0 的协议一样适用。考虑到授权码许可是最完备、最安全的许可类型,在移动 App 如何使用 OAuth 2.0 的时候,依然会用授权码许可来讲解,毕竟“要用就用最好的”。


当开发一款移动 App 的时候,可以选择没有 Server 端的 “纯 App” 架构,比如这款 App 不需要跟自己的 Server 端通信,或者可以调用其它开放的 HTTP 接口;

当然也可以选择有服务端的架构,比如这款 App 还想把用户的操作日志记录下来并保存到 Server 端的数据库中。

那总结下来呢,移动 App 可以分为两类

  • 一类是没有 Server 端的 App 应用
  • 一类是有 Server 端的 App 应用。

图1 两类移动App

这两类 App 在使用 OAuth 2.0 时的最大区别,在于获取访问令牌的方式

  • 如果有 Server 端,就建议通过 Server 端和授权服务做交互来换取访问令牌
  • 如果没有 Server 端,那么只能通过前端通信来跟授权服务做交互,比如隐式许可授权类型。当然,这种方式的安全性就降低了很多。

有些时候,可能觉得自己开发一个 App 不需要一个 Server 端。

那好,就让先来看看没有 Server 端的 App 应用如何使用授权码许可类型。


一、没有 Server 端的 App

在一个没有 Server 端支持的纯 App 应用中,首先想到的是,如何可以像 Web 服务那样,让请求和响应“来去自如”呢。

是不是可以将一个“迷你”的 Web 服务器嵌入到 App 里面去,这样不就可以像 Web 应用那样来使用 OAuth 2.0 了么?确实,这是行得通的,而且已经有 App 这样做了。

这样的 App 通过监听运行在 localhost 上的 Web 服务器 URI,就可以做到跟普通的 Web 应用一样的通信机制,但这种方式不是这次要讲的重点。

因为当使用这种方式的时候,请求访问令牌时需要的 app_secret 就只能保存在用户本地设备上,而这并不是所建议的。

到这里,问题的关键在于如何保存 app_secret,因为 App 会被安装在成千上万个终端设备上,app_secret 一旦被破解,就将会造成灾难性的后果。

这时,有的同学突发奇想,如果不用 app_secret,也能在授权码流程里换回访问令牌 access_token,不就可以了吗?但新的问题也来了。

在授权码许可类型的流程中,如果没有了 app_secret 这一层的保护,那么通过授权码 code 换取访问令牌的时候,就只有授权码 code 在“冲锋陷阵”了。授权码 code 一旦失窃,就会带来严重的安全问题。

那么,既不使用 app_secret,还要防止授权码 code 失窃,有什么好的方法吗?

有,OAuth 2.0 里面就有这样的指导方法。这个方法就是 PKCE 协议,全称是 Proof Key for Code Exchange by OAuth Public Clients。

在下面的流程图中,为了突出第三方软件使用 PKCE 协议时与授权服务之间的通信过程,省略了受保护资源服务和资源拥有者的角色:

图2 使用PKCE协议的流程图

首先,App 自己要生成一个随机的、长度在 43~128 字符之间的、参数为 code_verifier 的字符串验证码;

接着,再利用这个 code_verifier,来生成一个被称为“挑战码”的参数code_challenge。那怎么生成这个 code_challenge 的值呢?

OAuth 2.0 规范里面给出了两种方法,就是看 code_challenge_method 这个参数的值:

  • 一种 code_challenge_method=plain,此时 code_verifier 的值就是 code_challenge 的值;
  • 另外一种 code_challenge_method=S256,就是将 code_verifier 值进行 ASCII 编码之后再进行哈希,然后再将哈希之后的值进行 BASE64-URL 编码,如下代码所示。
code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))

好了,知道有这样两个值,也知道它们的生成方法了,但这两个值跟我们的授权码流程有什么关系呢,又怎么利用它们呢?

授权码流程简单概括起来不是有两步吗,第一步是获取授权码 code,第二步是用 app_id+app_secret+code 获取访问令牌 access_token。

刚才“梦想”不是设想不使用 app_secret,但同时又能保证授权码流程的安全性么?没错。

code_verifier 和 code_challenge 这两个参数,就是来帮实现这个“梦想”的。

在第一步获取授权码 code 的时候,使用 code_challenge 参数。

需要注意的是,要同时将 code_challenge_method 参数也传过去,目的是让授权服务知道生成 code_challenge 值的方法是 plain 还是 S256。

https://authorization-server.com/auth?
response_type=code&
app_id=APP_ID&
redirect_uri=REDIRECT_URI&
code_challenge=CODE_CHALLENGE&
code_challenge_method=S256

在第二步获取访问令牌的时候,使用 code_verifier 参数,授权服务此时会将 code_verifier 的值进行一次运算。

那怎么运算呢?就是上面 code_challenge_method=S256 的这种方式。

没错,第一步请求授权码的时候,已经告诉授权服务生成 code_challenge 的方法了。

所以,在第二步的过程中,授权服务将运算的值跟第一步接收到的值做比较,如果相同就颁发访问令牌。

POST https://api.authorization-server.com/token?grant_type=authorization_code&code=AUTH_CODE_HERE&redirect_uri=REDIRECT_URI&app_id=APP_ID&code_verifier=CODE_VERIFIER

现在,就知道了是如何使用 code_verifier 和 code_challenge 这两个参数的了吧。

总结一下就是,换取授权码 code 的时候,使用 code_challenge 参数值;换取访问令牌的时候,使用 code_verifier 参数值。

为什么要这样做呢。愿望是,没有 Server 端的手机 App,也可以使用授权码许可流程,对吧?

app_secret 不能用,因为它只能被存在用户的设备上,担心被泄露。

那么,在没有了 app_secret 这层保护的前提下,即使授权码 code 被截获,再加上 code_challenge 也同时被截获了,那也没有办法由 code_challenge 逆推出 code_verifier 的值。而恰恰在第二步换取访问令牌的时候,授权服务需要的就是 code_verifier 的值。

因此,这也就避免了访问令牌被恶意换取的安全问题。现在,可以通过 PKCE 协议的帮助,让没有 Server 端的 App 也能够安全地使用授权码许可类型进行授权了。

按照 OAuth 2.0 的规范建议,通过后端通信来换取访问令牌是较为安全的方式。

在做移动应用开发的时候,真的从设计上就决定废弃 Server 端了吗?


二、有 Server 端的 App

如果开发接入过微信登录,就会在微信的官方文档上看到下面这句话:

微信 OAuth 2.0 授权登录目前支持 authorization_code 模式,适用于拥有 Server 端的应用授权。

没错,微信的 OAuth 2.0 授权登录,就是建议需要一个 Server 端来支持这样的授权接入。

那么,有 Server 端支持的 App 又是如何使用 OAuth 2.0 的授权码许可流程的呢?

仍以微信登录为例,看一下官方的流程图:

在这里插入图片描述

看到这个图,是不是觉得特别熟悉,跟普通的授权码流程没有区别,仍是两步走的策略:

  • 第一步换取授权码 code
  • 第二步通过授权码 code 换取访问令牌 access_token。

这里的第三方应用,就是我们作为开发者来开发的应用,包含了移动 App 和 Server 端。

将其“放大”得到下面这张图:

图4 有Server端的App的授权流程

从这张“放大”的图中,就会发现有 Server 端的 App 在使用授权码流程的时候,跟普通的 Web 应用几乎没有任何差别

  1. 大概流程是:当访问第三方 App 的时候,需要用到微信来登录;
  2. 第三方 App 可以拉起微信的 App,会在微信的 App 里面进行登录及授权;
  3. 微信 Server 端验证成功之后会返回一个授权码 code,通过微信 App 传递给了第三方 App;
  4. 后面的流程就是熟悉的使用授权码 code 和 app_secret,换取访问令牌 access_token 的值了。

这次使用 app_secret 的时候,是在第三方 App 的 Server 端来使用的,因此安全性上没有任何问题。


三、总结

没有 Server 端的 App有 Server 端的 App 分别是如何使用授权码许可类型的。

  • 使用 OAuth 2.0 协议的目的,就是要起到安全性的作用,但有些时候,因为使用不当反而会造成更大的安全问题,比如将 app_secret 放入 App 中的最基本错误。如果放弃了 app_secret,又是如何让没有 Server 端的 App 安全地使用授权码许可协议呢?针对这种情况,介绍了 PKCE 协议。它是一种在失去 app_secret 保护的时候,防止授权码失窃的解决方案。
  • App 时候真的不需要一个 Server 端吗?建议你在开发移动 App 的时候,尽可能地都要搭建一个 Server 端,因为通过后端通信来传输访问令牌比通过前端通信传输要安全得多。也举了微信的例子,很多官方的开放平台在提供 OAuth 2.0 服务的时候,都会建议开发者要有一个相应的 Server 端。

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

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

相关文章

STM32 CubeMX (第一步Freertos任务管理:创建、删除、挂起、恢复)

STM32 CubeMX Freertos STM32 CubeMX (Freertos任务:创建、删除、挂起、恢复) STM32 CubeMX Freertos前言一、STM32 CubeMX 配置时钟树配置HAL时基选择TIM1(不要选择滴答定时器;滴答定时器留给OS系统做时基&#xff09…

6.RocketMQ之索引文件ConsumeQueue

本文着重分析为consumequeue/topic/queueId目录下的索引文件。 1.ConsumeQueueStore public class ConsumeQueueStore {protected final ConcurrentMap<String>, ConcurrentMap<Integer>, ConsumeQueueInterface>> consumeQueueTable;public boolean load(…

git权限问题解决方法Access denied fatal: Authentication failed

文章目录 遇到Access denied 的权限问题解决方法1、git的密码修改过&#xff0c;但是本地没更新。2、确定问题&#xff0c;然后增加配置① 查询用户信息②如果名称和email不对&#xff0c;设置名称&#xff1a;③ 检查ssh-add是否链接正常④ 设置不要每次都输入用户名密码 3、配…

[Mac软件]MacCleaner 3 PRO 3.2.1应用程序清理和卸载

应用介绍 MacCleaner PRO是一个应用程序包&#xff0c;将帮助您清除磁盘空间并加快Mac的速度&#xff01; MacCleaner PRO - 让您的Mac始终快速、干净和有条理。 App Cleaner & Uninstaller PRO - 完全删除未使用的应用程序并管理Mac扩展。 磁盘空间分析仪PRO-分析磁盘空…

无涯教程-Perl - setnetent函数

描述 该函数应在第一次调用getnetent之前调用。 STAYOPEN参数是可选的,在大多数系统上未使用。当getnetent()从网络数据库的下一行检索信息时,setnetent会将枚举设置(或重置)为主机条目集的开头。 语法 以下是此函数的简单语法- setnetent STAYOPEN返回值 此函数不返回任何…

基于安防监控EasyCVR视频汇聚融合技术的运输管理系统的分析

一、项目背景 近年来&#xff0c;随着物流行业迅速发展&#xff0c;物流运输费用高、运输过程不透明、货损货差率高、供应链协同能力差等问题不断涌现&#xff0c;严重影响了物流作业效率&#xff0c;市场对于运输管理数字化需求愈发迫切。当前运输行业存在的难题如下&#xf…

css学习1

1、样式定义如何显示元素。 2、样式通常保存至外部的css文件中。 3、样式可以使内容与表现分离。 4、css主要有两部分组成&#xff1a;选择器与一条或多条声明。 选择器通常为要改变的html元素&#xff0c;每条声明由一个属性和一个值组成。每个属性有一个值&#xff0c;属性…

WebStorm运行vue项目

WebStorm运行vue项目&#xff08;vue2&#xff09; 1.安装webstorm 2. 需要安装node.js 环境&#xff0c;可以去官网下载 https://nodejs.org/en 3. 安装完需要查看 按winr 输入cmd进入 输入命令node -v 和npm -v 查看&#xff0c;会出现相应的版本号,代表安装成功 vue官网安…

CF 1354 C1 C2 Polygon Embedding(求奇偶正多边形的外接最小正方形的边长)

CF 1354 C1 / C2 Polygon Embedding(求奇偶正多边形的外接最小正方形的边长) Problem - C1 - Codeforces Problem - C2 - Codeforces EASY &#xff1a; 大意&#xff1a;给出一个偶数 n &#xff0c; 求 正 (2 * n) 边形的最小外接正方形的边长。 可以想出两种最直观的情况…

Qt扫盲-Qt Paint System 概述

Qt Paint System 概述 一、概述二、绘图设备和后端1. Widget2. Image3. Pixmap4. OpenGL绘制设备5. Picture6. 自定义绘制后端 三、绘图与填充1. Drawing2. 填充 Filling 四、坐标系统1. 渲染Window-Viewport转换 五、读写图像文件1. QMovie 六、绘图相关设备 一、概述 Qt的pa…

生成国密SM2密钥对

在线生成国密密钥对 生成的密钥对要妥善保管&#xff0c;丢失是无法找回的。

Windows小记

一、域控制器升级的先决条件验证失败。 新建域时&#xff0c;本地 Administrator 帐户将成为域 Administrator 帐户。无法新建域&#xff0c;因为本地 Administrator 帐户密码不符合要求。 目前&#xff0c;本地 Administrator 帐户不需要密码。我们建议你使用网络用户命令行工…