如何对接口鉴权这样一个功能开发做面向对象分析?

1.第一轮基础分析

对于如何做鉴权这样一个问题, 最简单的解决方案就是, 通过用户名加密码来做认证。 我们 给每个允许访问我们服务的调用方, 派发一个应用名 (或者叫应用 ID、 AppID) 和一个对 应的密码(或者叫秘钥) 。 调用方每次进行接口请求的时候, 都携带自己的 AppID 和密 码。 微服务在接收到接口调用请求之后, 会解析出 AppID 和密码, 跟存储在微服务端的 AppID 和密码进行比对。 如果一致, 说明认证成功, 则允许接口调用请求; 否则, 就拒绝接口调用请求。

2. 第二轮分析优化

不过, 这样的验证方式, 每次都要明文传输密码。 密码很容易被截获, 是不安全的。 那如果 我们借助加密算法(比如 SHA) , 对密码进行加密之后, 再传递到微服务端验证, 是不是 就可以了呢?实际上, 这样也是不安全的, 因为加密之后的密码及 AppID, 照样可以被未 认证系统(或者说黑客)截获, 未认证系统可以携带这个加密之后的密码以及对应的 AppID, 伪装成已认证系统来访问我们的接口。 这就是典型的“  重放攻击” 。 提出问题, 然后再解决问题, 是一个非常好的迭代优化方法。 对于刚刚这个问题, 我们可以 借助 OAuth 的验证思路来解决。 调用方将请求接口的 URL 跟 AppID、 密码拼接在一起, 然后进行加密, 生成一个 token。 调用方在进行接口请求的的时候, 将这个 token 及 AppID, 随 URL 一块传递给微服务端。 微服务端接收到这些数据之后, 根据 AppID 从数 据库中取出对应的密码, 并通过同样的 token 生成算法, 生成另外一个 token。 用这个新 生成的 token 跟调用方传递过来的 token 对比。 如果一致, 则允许接口调用请求; 否则, 就拒绝接口调用请求。
在这里插入图片描述

2. 第三轮分析优化

  1. 不过, 这样的设计仍然存在重放攻击的风险, 还是不够安全。 每个 URL 拼接上 AppID、 密 码生成的 token
    都是固定的。 未认证系统截获 URL、 token 和 AppID 之后, 还是可以通 过重放攻击的方式, 伪装成认证系统,
    调用这个 URL 对应的接口。 为了解决这个问题, 我们可以进一步优化 token 生成算法, 引入一个随机变量, 让每次接
    口请求生成的 token 都不一样。 我们可以选择时间戳作为随机变量。 原来的 token 是对 URL、 AppID、
    密码三者进行加密生成的, 现在我们将 URL、 AppID、 密码、 时间戳四者 进行加密来生成 token。
    调用方在进行接口请求的时候, 将 token、 AppID、 时间戳, 随 URL 一并传递给微服务端。
    微服务端在收到这些数据之后, 会验证当前时间戳跟传递过来的时间戳, 是否在一定的时间 窗口内 (比如一分钟) 。 如果超过一分钟,
    则判定 token 过期, 拒绝接口请求。 如果没有 超过一分钟, 则说明 token 没有过期, 就再通过同样的 token
    生成算法, 在服务端生成新
    的 token, 与调用方传递过来的 token 比对, 看是否一致。 如果一致, 则允许接口调用请 求; 否则,
    就拒绝接口调用请求。
    在这里插入图片描述

4. 第四轮分析优化

  1. . 不过, 你可能会说, 这样还是不够安全啊。 未认证系统还是可以在这一分钟的 token 失效 窗口内, 通过截获请求、 重放请求,
    来调用我们的接口啊! 你说得没错。 不过, 攻与防之间, 本来就没有绝对的安全。 我们能做的就是, 尽量提高攻击 的成本。
    这个方案虽然还有漏洞, 但是实现起来足够简单, 而且不会过度影响接口本身的性 能(比如响应时间) 。 所以, 权衡安全性、 开发成本、
    对系统性能的影响, 这个方案算是比 较折中、 比较合理的了。

    实际上, 还有一个细节我们没有考虑到, 那就是, 如何在微服务端存储每个授权调用方的 AppID 和密码。 当然, 这个问题并不难。
    最容易想到的方案就是存储到数据库里, 比如 MySQL。 不过, 开发像鉴权这样的非业务功能, 最好不要与具体的第三方系统有过度的耦
    合。 针对 AppID 和密码的存储, 我们最好能灵活地支持各种不同的存储方式, 比如 ZooKeeper、 本地配置文件、
    自研配置中心、 MySQL、 Redis 等。 我们不一定针对每种存 储方式都去做代码实现, 但起码要留有扩展点,
    保证系统有足够的灵活性和扩展性, 能够在 我们切换存储方式的时候, 尽可能地减少代码的改动。

5. 最终确定需求

到此, 需求已经足够细化和具体了。 现在, 我们按照鉴权的流程, 对需求再重新描述一下。 如果你熟悉 UML, 也可以用时序图、 流程图来描述。 不过, 用什么描述不是重点, 描述清 楚才是最重要的。 考虑到在接下来的面向对象设计环节中,
我会基于文字版本的需求描述, 来进行类、 属性、 方法、 交互等的设计, 所以, 这里我给出的最终需求描述是文字版本的。
这就是我们需求分析的整个思考过程, 从最粗糙、 最模糊的需求开始, 通过“提出问题 - 解决问题” 的方式, 循序渐进地进行优化,
最后得到一个足够清晰、 可落地的需求描述。 重点回顾 今天的内容到此就讲完了。 我们一块来总结回顾一下, 你需要掌握的一些重点内容。
调用方进行接口请求的时候, 将 URL、 AppID、 密码、 时间戳拼接在一起, 通过加密算 法生成 token, 并且将
token、 AppID、 时间戳拼接在 URL 中, 一并发送到微服务端。 微服务端在接收到调用方的接口请求之后, 从请求中拆解出
token、 AppID、 时间戳。 微服务端首先检查传递过来的时间戳跟当前时间,是否在 token 失效时间窗口内。 如果
已经超过失效时间, 那就算接口调用鉴权失败, 拒绝接口调用请求。 如果 token 验证没有过期失效, 微服务端再从自己的存储中, 取出
AppID 对应的密 码, 通过同样的 token 生成算法, 生成另外一个 token, 与调用方传递过来的 token 进 行匹配;
如果一致, 则鉴权成功, 允许接口调用, 否则就拒绝接口调用。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值