需求
实现一个接口鉴权的功能,实现思路
1.调用端下发一个appId和秘钥
2.调用端将每次传过来的参数url后面都要带上appId+时间戳同时根据url+appId+时间戳+参数+秘钥进行MD5加密后通过token参数传过来
3.获取时间戳判断是否过期(假定1分钟) 如果过期鉴权失败
4.服务端解析出url+appId+时间戳+参数+秘钥进行md5加密
5.根据token匹配 如果不匹配 则认为参数被篡改 则鉴权失败
方式一
把需求描述中的名词罗列出来,作为可能的候选类,然后再进行筛选。对于没有经验的初学者来说,这个方法比较简单、明确,可以直接照着做。
我想到的几个名词 囧
鉴权
解析
加密
方式二
类的大致拆解
将上面的需求拆分成一个一个尽可能小的功能点"单一职责"
1.解析url获取参数、token、时间戳
2.从存储中根据appId获取秘钥
3.将url+appId+时间戳+参数+秘钥+拼成一个串
4.对字符串进行加密生成一个token
5.根据时间戳判断是否token过期(防止接口重放)
6.对加密后的token和调用方穿过来的token判断是否一致(防止参数篡改)
3 4 5 6都是跟token相关 负责token的生成验证,1负责解析url,2.操作appid和密码
所以,我们可以粗略地得到三个核心的类:AuthToken、Url、CredentialStorage。AuthToken 负责实现 3 4 5 6这四个操作;Url 负责 1两个操作;CredentialStorage 负责 2 这个操作
类的定义
AuthToken
3.将url+appId+时间戳+参数+秘钥+拼成一个串
4.对字符串进行加密生成一个token
5.根据时间戳判断是否token过期
6.对加密后的token和调用方穿过来的token判断是否一致
对于方法的识别,很多面向对象相关的书籍,一般都是这么讲的,识别出需求描述中的动词,作为候选的方法,再进一步过滤筛选。类比一下方法的识别,我们可以把功能点中涉及的名词,作为候选属性,然后同样进行过滤筛选
动词: 1.拼接串 2.判断是否过期 3.生成token 4.是否匹配 但是拼接串和生成token其实都是为生成token服务所以实现了2个方法1.isExpired判断是否过期 2.match是否匹配
注意点:
- 从业务模型上来说,不应该属于这个类的属性和方法,不应该被放到这个类里。比如 URL、AppID 这些信息,从业务模型上来说,不应该属于 AuthToken,所以我们不应该放到这个类中。
- 在设计类具有哪些属性和方法的时候,不能单纯地依赖当下的需求,还要分析这个类从业务模型上来讲,理应具有哪些属性和方法。这样可以一方面保证类定义的完整性,另一方面不仅为当下的需求还为未来的需求做些准备。
Url
1.解析url获取参数、token、时间戳
虽然需求描述中,我们都是以 URL 来代指接口请求,但是,接口请求并不一定是以 URL 的形式来表达,还有可能是 dubbo RPC 等其他形式。为了让这个类更加通用,命名更加贴切,我们接下来把它命名为 ApiRequest。下面是我根据功能点描述设计的 ApiRequest 类。
CredentialStorage
2.从存储中根据appId获取秘钥
定义类与类之间的交互关系