1、 如何进行面向对象分析、设计与编程 、
实际开发过程中,我们大部分开发都是curd,业务增删改查,导致产品、业务分析能力较差,当拿到一个模糊笼统得业务需求得时候,不知道怎么开发.一般拥有如下问题?
- 如何做需求分析 ?
- 如何做职责划分 ?
- 需要定义哪些类 ?
- 每个类应该具有哪些属性 ?
- 每个类应该具有哪些类与类之间该如何交互 ?
- 如何组装类成一个可执行的程序 ?
2、 案例介绍和难点剖析
开发一个微服务项目, 微服务通过 HTTP 协议暴露接口给其他系统调用,业务需求: 为了保证接口调用的安全性,我们希望设计实现一个接口调用鉴权功能,只有经过认 证之后的系统才能调用我们的接口,没有认证过的系统调用我们的接口会被拒绝。
2.1、 需求不明确
- leader 给到的需求过于模糊、笼统,不够具体、细化,离落地到设计、编码还有一定的距离
- 首先要做的都是将笼 统的需求细化到足够清晰、可执行 .
2.2、 缺少锻炼
- 鉴权这个开发任务,要更有难度。鉴权作为一个跟具体业务 无关的功能,我们完全可以把它开发成一个独立的框架,集成到很多业务系统中。而作为被 很多系统复用的通用框架,比起普通的业务代码,我们对框架的代码质量要求要更高
- 开发这样通用的框架,对工程师的需求分析能力、设计能力、编码能力,甚至逻辑思维能力 的要求,都是比较高的。
3、 对案例进行需求分析
- 了解具体的应用场景
- 多跟业务团队聊聊天 了解实际业务需求
- 去参 与几个业务系统的开发 , 真正知道业务系统的痛点 ,能分析出最有价 值的需求 。
- 先从满足我们自己系统的需求开始,然后再迭代优化
3.1、 第一轮基础分析
如何做鉴权? 1.最简单的解决方案 : 用户名加密码来做认证 。
- 每个允许访问我们服务的调用方 分一个唯一得id+ 和一个对 应的密码(或者叫秘钥)
- 微服务在接收到接口调用请求之后 验证账号密码成功->允许访问失败,不允许访问.
3.2、 第二轮分析优化
第一种方式缺点:这种密码容易破解(这是一种明文方式) 1: 如果我们借助加密算法(比如 SHA),对密码进行加密之后,再传递到微服务端验证,是不是 以了 呢 ? 实际上,这样也是不安全的,因为加密之后的密码及 AppID,看下面”重放攻击” 2:”重放攻击”: 照样可以被未 认证系统(或者说黑客)截获,未认证系统可以携带这个加密之后的密 码以及对应的 AppID,伪装成已认证系统来访问我们的接口。
3: 我们可以 借助 OAuth 的验证思路来解决
1.调用方将请求接口的 URL 跟 AppID、密码拼接在一起, 然后进行加密,生成一个 token
2.调用方在进行接口请求的的时候,将这个 token 及 AppID,随 URL 一块传递给微服务端
3.根据 AppID 从数 据库中取出对应的密码,并通过同样的 token 生成算法,生成另外一个 token。
4.用这个新 生成的 token 跟调用方传递过来的 token 对比。如果一致,则允许接口调用请求
3.3、 第三轮分析优化
- 每个 URL 拼接上 AppID、密 码生成的 token 都是固定的。未认证系统截获 URL、token 和 AppID 之后,还是可以通 过重放攻击的方式,伪装成认证系统,调用这个 URL 对应的接口。
- 进一步优化 token 生成算法,引入一个随机变量,让每次接 口请求生成的 token 都不一样。我们可以选择时间戳作为随机变量
- 原来的 token 是对 URL、AppID、密码三者进行加密生成的
- 现在我们将 URL、AppID、密码、时间戳四者 进行加密来生成 token
- 微服务端在收到这些数据之后,会验证当前时间戳跟传递过来的时间戳,是否在一定的时间 窗口内(比如一分钟)。如果超过一分钟,则判定 token 过期,拒绝接口请求。如果没有 超过一分钟,则说明 token 没有过期
3.4、 第四轮分析优化
1、 未认证系统还是可以在这一分钟的 token 失效 窗口内,通过截获请求、重放请求,来调用我们的接口啊 ?导致失效. 2、 如何在微服务端存储每个授权调用方的 AppID 和密码 ? 我们最好能灵活地支持各种不同的存储方式,比如 ZooKeeper、本地配置文件、自研配置中心、MySQL、Redis 等
3.5、 最终确定需求
- 将 URL、AppID、密码、时间戳拼接在一起,通过加密算 法生成 token,并且将 token、AppID、时间戳拼接在 URL 中,一并发送到微服务端
- 微服务端在接收到调用方的接口请求之后,从请求中拆解出 token、AppID、时间戳。
- 微服务端首先检查传递过来的时间戳跟当前时间,是否在 token 失效时间窗口内。如果 已经超过失效时间,那就算接口调用鉴权失败,拒绝接口调用请求
- 如果 token 验证没有过期失效,微服务端再从自己的存储中,取出 AppID 对应的密 码
- 通过同样的 token 生成算法,生成另外一个 token,与调用方传递过来的 token 进 行匹配;如果一致,则鉴权成功,允许接口调用,否则就拒绝接口调用。