需求:安全性要求较高的接口暴露到公网中,需要进行加密和限频.
案例:根据用户手机号查询用户ID,需要防止根据phone库非法扫接口,
1.返回uid加密:
采用RSA加密,私钥加密,公钥解密,为了混淆结果,无论有无uid都返回加密结果。当无结果会根据phone md5截取7位
作为伪号,使用另一私钥加密。如果公钥解密失败则说明无对应uid。
2.限频,根据key=access_token 50次每天。limit50; timeunit:day
public long incr(String key) {
long count = redisTemplate.opsForValue().increment(key, 1);
if (count == 1) {
// 暂时不考虑设置超时时间失败的情况
redisTemplate.expire(key, 1, timeUnit);
}
if (count > limit) {
// 超过临界值之后, 每次错误都延长记录有效期
redisTemplate.expire(key, 1, timeUnit);
}
return count;
}
public long getCountByKey(String key){
long count = redisTemplate.execute((RedisCallback<Long>) (conn) -> {
byte[] countStr = conn.get(key.getBytes(StandardCharsets.UTF_8));
if (countStr == null) {
return 0L;
}
return Long.parseLong(new String(countStr));
});
return count;
}
public void check(String key) {
if (getCountByKey(key) > limit) {
throw new TooManyFailsException();
}
}