博客列表 >php实现对短信验证码发送次数的限制实例讲解

php实现对短信验证码发送次数的限制实例讲解

P粉526161432
P粉526161432原创
2022年03月27日 11:01:38709浏览
  1. 这篇文章主要介绍了php实现对短信验证码发送次数的限制实例讲解,案例中列举了具体代码实现,有感兴趣的同学可以学习下
  1. 场景
  2. 在注册,修改密码,找回密码等场景里,我们都会遇到发送手机短信进行验证码验证,我们都知道,手机的这个短信接口是需要购买了,为了防刷,我们就会对短信验证码发送次数的限制,我们应该如何防止呢?
  3. 很多人都会这样做:对用户获取短信验证码的手机号、ip、和浏览器(使用唯一标识)进行限制。
  4. 本文介绍的方法是对用户每天只能通过同一浏览器或同一ip地址获取验证码10次或者同一手机号只能获取3次短信验证码,三种限制为“或”关系,一条超限就不发验证码。方法是通过在服务器端将用户的手机号、ipur_r标识记录并写入文件,再通过读取文件记录判断用户请求发送验证码的次数来做限制。
  5. 方法如下:
  6. 这里是获取短信验证码页面:
  1. <!DOCTYPE html>
  2. <html>
  3. <head></head>
  4. <body>
  5. <!-- 隐藏表单uv_r标识,用于对获取验证码的浏览器进行限制,唯一标识存储于浏览器cookie中。在用户进行获取短信验证码操作时将标识传入后台代码(可以通过js传入后台,此处未提供js代码) -->
  6. <input type="hidden" name="uv_r" value="" id="uv_r">
  7. </body>
  8. <script type=”text/javascript”>
  9. /*
  10. 使用js获取cookieur_r唯一标识,如果不存在,生成唯一标识,js写入cookie,并将唯一标识赋给隐藏表单。
  11. */
  12. //唯一标识存入cookie
  13. var _uuid = getUUID();
  14. if(getCookie("_UUID_UV")!=null && getCookie("_UUID_UV")!=undefined)
  15. {
  16. _uuid = getCookie("_UUID_UV");
  17. }else{
  18. setCookie("_UUID_UV",_uuid);
  19. }
  20. document.getElementById("uv_r").value = _uuid;//赋给hidden表单
  21. //生成唯一标识
  22. function getUUID()
  23. {
  24. var uuid = new Date().getTime();
  25. var randomNum =parseInt(Math.random()*1000);
  26. return uuid+randomNum.toString();
  27. }
  28. //写cookie
  29. function setCookie(name,value)
  30. {
  31. var Days = 365;//这里设置cookie存在时间为一年
  32. var exp = new Date();
  33. exp.setTime(exp.getTime() + Days*24*60*60*1000);
  34. document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString();
  35. }
  36. //获取cookie
  37. function getCookie(name)
  38. {
  39. var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)");
  40. if(arr=document.cookie.match(reg))
  41. return unescape(arr[2]);
  42. else
  43. return null;
  44. }
  45. </script>
  46. </html>
  1. 后端PHP短信限制次数等的封装类:
  1. Class regMod{
  2. //定义全局变量,用于设置记录文件的路径
  3. Protected $Root = null;
  4. Public function __construct(){
  5. $this -> Root = APP_PATH."/data/msg_logs/";//自己定义的文件存放位置
  6. }
  7. //获取短信验证码操作(Ajax方法为好)
  8. Public function get_authentication_code(){
  9. if ($_POST['uv_r'] && $_POST['tel']) {
  10. $ip=$_SERVER["REMOTE_ADDR"];//ip
  11. $tel = $_POST['tel'];//电话
  12. $uv_r = $_POST['uv_r'];//ur_r标识
  13. if(empty($uv_r)){
  14. $uv_r = 0;
  15. }
  16. }
  17. //判断数据是否超过了限制
  18. $uvr_num = $this->checkUvr($uv_r);
  19. $tel_num = $this->checkTel($tel);
  20. $ip_num = $this->checkIp($ip);
  21. if ($uvr_num < 10 && $tel_num < 4 && $ip_num < 10) {
  22. Echo "发送验证码";//符合发送条件,发送验证码的操作
  23. } else {
  24. Echo “不发送验证码”;
  25. //当不发送验证码时,将数据存入文件,用于方便查询
  26. $data = $tel . "|" . $ip . "|" . $uv_r . "|";
  27. if ($uv_r>0 && $uvr_num >= 10) {
  28. $data = $data . "A@";
  29. }
  30. if ($tel_num >= 4) {
  31. $data = $data . "B@";
  32. }
  33. if ($ip_num >= 10) {
  34. $data = $data . "C@";
  35. }
  36. $this->wirteFile("", $data);
  37. $this->ajax_return(0, "您今日获取短信验证码的次数过多!");//给用户返回信息,ajax_return()为自写方法(未提供)
  38. }
  39. }
  40. //以下方法为私有方法
  41. //检测ur_r在文件中出现的次数
  42. Private function checkUvr($data){
  43. $fileName = "Uv_".date("Ymd",time()).".dat";
  44. $filePath = ($this -> Root).$fileName;//组装要写入的文件的路径
  45. $c_sum = 0;
  46. if(file_exists($filePath)){//文件存在获取次数并将此次请求的数据写入
  47. $arr=file_get_contents($filePath);
  48. $row=explode("|",$arr);
  49. $countArr=array_count_values($row);
  50. $c_sum = $countArr[$data];
  51. if($c_sum<10)
  52. {
  53. $this -> wirteFile($filePath,$data."|");
  54. }
  55. return $c_sum;
  56. }else{//文件不存在创建文件并写入本次数据,返回次数0
  57. $this -> wirteFile($filePath,$data."|");
  58. return $c_sum;
  59. }
  60. }
  61. //检测Tel在文件中出现的次数
  62. Private function checkTel($data){
  63. $fileName = "Tel_".date("Ymd",time()).".dat";
  64. $filePath = ($this -> Root).$fileName;
  65. $c_sum = 0;
  66. if(file_exists($filePath)){
  67. $arr=file_get_contents($filePath);
  68. $row=explode("|",$arr);
  69. $countArr=array_count_values($row);
  70. $c_sum = $countArr[$data];
  71. if($c_sum<4)
  72. {
  73. $this -> wirteFile($filePath,$data."|");
  74. }
  75. return $c_sum;
  76. }else{
  77. $this -> wirteFile($filePath,$data."|");
  78. return $c_sum;
  79. }
  80. }
  81. //检测IP在文件中存在的次数
  82. Private function checkIp($data){
  83. $fileName = "Ip_".date("Ymd",time()).".dat";
  84. $filePath = ($this -> Root).$fileName;
  85. $c_sum = 0;
  86. if(file_exists($filePath)){
  87. $arr=file_get_contents($filePath);
  88. $row=explode("|",$arr);
  89. $countArr=array_count_values($row);
  90. $c_sum = $countArr[$data];
  91. if($c_sum<10)
  92. {
  93. $this -> wirteFile($filePath,$data."|");
  94. }
  95. return $c_sum;
  96. }else{
  97. $this -> wirteFile($filePath,$data."|");
  98. return $c_sum;
  99. }
  100. }
  101. /**
  102. * 将数据写入本地文件
  103. * @param $filePath 要写入文件的路径
  104. * @param $data 写入的数据
  105. */
  106. Private function wirteFile($filePath,$data){
  107. try {
  108. if(!is_dir($this->Root)){//判断文件所在目录是否存在,不存在就创建
  109. mkdir($this->Root, 0777, true);
  110. }
  111. if($filePath==""){//此处是不发送验证码时,记录日志创建的文件
  112. $filePath = ($this -> Root)."N".date("Ymd",time()).".dat";
  113. }
  114. //写入文件操作
  115. $fp=fopen($filePath,"a+");//得到指针
  116. fwrite($fp,$data);//写
  117. fclose($fp);//关闭
  118. } catch (Exception $e) { print $e->getMessage(); }
  119. }
  120. }
  1. 接下来的一步就是你需要在哪里用到短信限制,比如注册,密码找回,修改密码等方法里,直接实例化此封装的类就可以用了。
  2. 到此这篇关于php实现对短信验证码发送次数的限制实例讲解的文章就介绍到这了,更多相关php实现对短信验证码发送次数的限制内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议