故事的开始,面试官问了我一个问题:
如何防止http请求中数据被篡改?
回答:
1.设置客户端IP黑/白名单
1.1.客户端所有请求,请求到代理服务器(nginx),代理服务器维护黑/白名单的ip,决定是否转发请求。
1.2.项目创建一个filter,拦截所有请求,在filter的方法中,通过request信息匹配ip黑/白名单,和url的拦截规则,决定是否合法。
优点:简单粗暴。
缺点:需要客户端的IP固定。
应用场景:并发量小的场景。比如系统的后台管理服务,客服需要人工审批和通过涉及到钱财的业务,就可以使用这种简单粗暴的方式,防止账号泄露,接口泄露等等。
2.请求参数Sign签名
2.1前端发起http请求,对参数排序,然后使用 参数与私钥拼接,在进行md5加密 等方式,生成一个签名出来,一起发给服务端,服务端这边获取到参数,签名,再使用自己的私钥进行同样方式的加密生成签名,比对签名是否一致。一致则认为合法,不一致则不合法。但是无法防止重复请求攻击!
2.2针对上面方法升级,可以缓存每次请求的md5值,或者给每个请求添加uuid+随机数这样一个代表请求序号的标识。然后请求到服务端时,服务端想办法缓存起来起来这个标识,每次请求过来时,判断是否已经请求过。但是缓存怎么实现,如何维护?而且并发量高的话,每个请求过来都先查缓存,是否影响性能。
2.3在请求的参数中和签名结果里,加入时间戳这个参数,业务服务器一方面比较签名结果,一方面根据时间戳,来认证请求的合法性,比如允许请求的时间戳与服务器当前时间,存在20秒的误差等自定义规则。超过20秒的合法请求,服务器也不处理,防止恶意的重复请求。
2.4时间戳+md51 时间差120s以上代表重复请求,md5写缓存,缓存时长120s(大于等于上面的值就行),判断如果有md5代表重复请求。
3.请求方式换成Https