有个短信接口给用户注册时发送验证码的,然后现在发现有人每次用不同ip 不同号码进行恶意调用,现在接口被调爆,如何解决这个问题呢。(现在的黑科技不只是有你想象中的那么简单的)
1,最简单有效的防护就是图片验证码,采用点触验证,验证滑动或者是第三方验证码服务,普通的图片验证码很
容易被破解
2,频率,或者叫接口防刷,通过用户具有唯一性的ip验证用户的身份,模拟一个场景,每次用户调用接口,将此用户的
ip进行记录,在有效的时间之内,用户每调用一次接口,给调用的次数+1,当超过(次数根据自己的时间情况进行定义)
当达到指定的次数时,将调用这个接口的用户ip加入黑名单中,当锁定(锁定时间根据实际情况进行定义)之后移除在
黑名单中的用户ip,进行解锁,但是每次用户在短时间内调用接口,实时记录的ip,次数,时间存到什么地方呢?
我们又很多种选择,数据库,文件,memcache, redis. 对于数据库或者是文件的操作,是吧数据存入在硬盘里,memcache或者是
redis是一种基于内存的分布式缓存,数据存到数据库,随着调用接口的频繁不仅仅会加大服务器的压力而且速度远远补不上存在内
存中的,剩下的两种缓存操作的我们选择了redis,因为redis支持的数据类型更多,支持永久存储,因为redis有部分是存储在了硬
盘上,有关redis于memcache的区别详解:https://www.cnblogs.com/JavaBlackHole/p/7726195.html
有关接口防刷的具体操作:
首先redis的扩展与服务都需要启动:https://blog.csdn.net/li_lening/article/details/81227423
public function checkRequest($ip){ #一分钟接口调用只能10次 $redis= new \Redis(); $redis->open('xxx',6379);//服务器连接的Ip与端口号 $redis->auth('xxx');//redis服务的密码 $redis->select(1);//选择连接的redis,默认redis的库有16个 // $redis->flushAll();exit;//清空redis的所有库 $lock_time=$redis->zScore('user_list',$ip);//返回有序集中key中成员member的score if(time()-$lock_time<3000){ return 1;//在黑名单中 }else{ $redis->zRem('user_list',$ip);//redis中zRem命令用于移除有序集合中的一个或者是多个成员,不存在的成员将被忽略,当key存在但是不是有序集合类型是,返回一个错误 } #记录访问次数 $ip_value=$redis->get($ip);//get命令用于获取指定的keyz值,如果key值不存在返回null if(!$ip_value){ #设置key自增 $redis->incr($ip);//将key中存储的数字值增1 #设置过期时间为3000秒 $redis->expire($ip,3000);//给key值设置生存时间 }else{ $redis->incr($ip); } #集合里边的元素不会重复 字符串 #把ip当做key 存入redis 存5分钟 if($ip_value>10){ #使用有序集合 $redis->zAdd('user_list',time(),$ip);//命令用于将一个或者是多个于是怒以及分数值加入到有序集合中 return 2;//调用接口频繁 } }
3, 签名,API接口启用签名策略,签名可以保障请求URL的完整安全,签名匹配再继续下一步操作,
4,token,对于重要的API接口,生成token值,做验证
应对接口安全,我们可以对数据进行加密,不明文传输数据,可以选择对称加密(DES 2DES)或者是非对称加密(RSA),
虽然说两者都是加密,但是又很大的区别,对称加密的速度快,但是相对非对称加密来说是不安全的,一旦一方泄露密钥,所有
的数据将全部泄露,对于加密的长度来说非对称加密有长度限制,密钥的长度是1024,值能加密117个字符,如果长度过长,还
需要分段加密,分段解密,效率更低,但是相对来说比较安全。
非对称加密如何实现:https://blog.csdn.net/li_lening/article/details/80830762
希望这些内容可以对你们有帮助