于我而言,如果是我,有个接口,该怎样让别人调用
1、直接将接口给出
直接访问 http://localhost:8001/api/post/user
优点:业务逻辑少,便于我写程序调用方便,用户方便调用(用户始终方便调用。。。)
缺点:如果有大量的请求的话,比如说
- 有人不是正常使用,而是用的Python爬虫大量调用;
- 或者一些人闲来无事故意攻击
写到这想起来哪些人可以调用接口
- 已登录会员
- 是否购买了相应的接口(这点先不要考虑)
- 如果是花钱的,并且只是购买次数的,接口不做任何限制
- 如果是花钱的,购买的是包月的,包年的话,限制频率和次数
- 是否有权限使用这个接口(怎么和上一点有异曲同工之处)
- 是否还有可以使用的次数
所以综上所述有了第二种调用方法
封装一个类作为SDK给出
那该怎么设计SDK?
用户给出拥有的accessKey和secretKey
方法:
- 已登录会员 // 验证session user(数据库)
- 是否购买了相应的接口(这点先不要考虑)// 查询数据库,添加到session
- 如果是花钱的,并且只是购买次数的,接口不做任何限制 //防止服务器挂掉,造成count不能及时同步造成损失,次数的加减直接请求数据库,不过这样速度会慢,资源浪费 count(数据库)
- 如果是花钱的,购买的是包月的,包年的话,限制频率和次数 // 直接同步到数据库,本来就限制频率,不用担心数据库快慢 :::::::::count (数据库)
- 频率 每个请求都记录一个ID 时间戳(内存),
- 是否有权限使用这个接口(怎么和上一点有异曲同工之处)
- 是否为试用接口
- 是否还有可以使用的次数
- 同上2.2
优化请求头,以及服务器后端的设置
private Map<String, String> getHeaderMap(String body) {
Map<String, String> hashMap = new HashMap<>();
hashMap.put("accessKey", accessKey);
hashMap.put("secretKey", secretKey);
hashMap.put("nonce", RandomUtil.randomNumbers(4));
hashMap.put("body", body);
hashMap.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
hashMap.put("sign", genSign(body, secretKey));
return hashMap;
}
修改:::
上述代码中 secretKey 不能直接发送,但是放在请求头中,随随便便都能获取,再加上其他的参数,参数数量又不多,排列组合,很随便就能得到genSign。
假如请求被vpn相关的服务拦截,获取到ak和sk,然后在设置时间戳,也是可以高频率的访问;
所以修改如下:
1、secretKey不放在请求头,只作为genSign计算的一部分,安全系数更高;
2、增加时间戳为genSign函数的参数,先获取时间戳,在去请求头,这样就算请求头的时间戳被人为设置,在后台在只需通过数据库获取secretKey,再加上请求头里的时间戳重新计算genSign,如果认为设置过时间戳,genSign就会不一致,直接拒绝请求。
第一次感觉,设置时间戳这么有用,越想越感觉这样牛皮,
这样,设置三四秒一次请求,比较符合人为的操作,感觉可以有效地防止被刷流量;
然后在设置是否规律,如过请求太过有规律,那么极有可能是爬虫,如果这个接口就是可以提供爬虫使用另说
如果不是,假如后端频率设置为每三秒一次请求,那么如果一分钟内超过十五次,就禁止这个接口;