在客户端与服务端请求交互的过程中,请求的数据容易被拦截并篡改,比如在支付场景中,请求支付金额为 10 元,被拦截后篡改为 100 元,由于没有防篡改校验,导致多支付了金钱,造成了用户损失。因此我们在接口设计时必须考虑防篡改校验,加签、验签就是用来解决这个问题的。划重点,敲黑板:加签、验签是用来解决防篡改问题的。
// 获取token String token = request.getHeader("token"); // 获取时间戳 String timestamp = request.getHeader("timestamp"); // 获取随机字符串 String nonceStr = request.getHeader("nonceStr"); // 获取请求地址 String url = request.getHeader("url"); // 获取签名 String signature = request.getHeader("signature");
常用的防止重放攻击策略主要分为以下两种:
1、基于 加时间戳的方案
2、基于 token 的方案
3、基于 时间戳和 token 的方案
基于时间戳的方案
在请求中增加时间戳参数要来表示请求时间戳,服务方端接收该请求后,根据当前时间生成一个接收时间戳,然后根据两个时间戳的差值进行请求判定,如果差值大于指定的阈值,则认为请求无效,否则请求通过。关于阈值的选定,可以根据接口的响应速度进行适当的调整,一般默认为 60 秒。
if((接收时间戳-请求时间戳) > 60){ "请求失败" } else { "请求通过" }
基于 token 的方案
在请求中增加一个通过指定规则产生的 token,标识请求的唯一性,服务方接收该请求后,先判断缓存集合中是否存在该 token,如果存在则认为此次请求无效,否则将 token 放入缓存中,通过请求通过。