IP白名单的实现(PHP)
IP白名单的实现(PHP)
有些项目可能会用到一个IP地址的白名单黑名单之类的验证。
比如,只有IP地址在白名单中,才可以访问该系统。
那么此时,白名单的维护,一般是一个文件,里边是一些IP地址(每行一个IP),当然也有的可能是用数据库记录白名单。
当然,即使放在数据库中记录(方便管理),也可以在后台根据数据库生成IP白名单的配置文件,每次更新白名单时,都根据数据库数据,重新写一下白名单的配置文件。
这里,假设白名单的IP地址是存储在一个文件中:while_ips.conf
一般常见的两种情况:一种是白名单文件中的所有IP都是完整的,另一种是有的IP是有范围的(带.*)
一、每一个IP都是完整的IP
1 127.0.0.0 2 192.168.1.1 3 192.168.1.2 4 192.168.1.30 5 123.200.20.200 6 123.101.21.201
以上假设就是IP白名单。
此时的思路是,从文件中读取所有IP地址写入一个数组,每行就是一个元素。
然后判断当前IP是否在这个数组中。这样就实现了这个IP是不是在白名单的验证。
这种实现,比较简单。
1 function white_ips($file) 2 { 3 $a = []; 4 if (is_file($file)) {// 判断是不是文件 5 $f = fopen($file, 'r');// 只读的方式打开文件 6 while (!feof($f)) {// 判断你是否在文件尾,不是文件尾则循环 7 $s = fgets($f);// 每次读出一行 8 $s = preg_replace('/\s*/', '', $s);// 先过滤掉多余的空格和空白 9 if (substr($s, 0, 1) != '#' && $s != '') {// 如果不是注释行,或者空行 10 $a[] = $s;// 记录有效数据 11 } 12 } 13 fclose($f); 14 } 15 return $a; 16 }
$file是IP白名单文件的存储位置和文件名,其中会过滤掉注释的IP,同时也会过滤掉多余的空白和换行。避免意外出错。
1 $arr = getWhiteIps('white_ips.conf'); 2 $ip = '192.168.1.1'; 3 $allow = 0; 4 if (in_array($ip, $arr)) { 5 $allow = 1; 6 } 7 echo $allow;
通过这样调用和判断,就可以知道当前的IP是否在白名单了。
二、第二种情况是白名单配置文件中是有范围的
1 127.*.*.* 2 10.*.*.* 3 192.168.*. * 4 192.168.1.1 5 123.200.20.200 6 123.101.21.201 7 210.10.22.* 8 210.123.135.* 9 #30.11.22.33 10 #119.123.2.15
以上是假设IP白名单的文件内容
此时的思路是,从文件中读取所有IP地址写入一个数组,每行就是一个元素。
然后通过循环的方式,将当前IP和数组中的每一条数据进行比较(匹配),如果匹配上则白名单,否则不是。
此时因为有范围,所以不能使用in_array这种简单的判断了。需要使用正则来判断。
读取白名单配置文件的代码不变,改变判断方法即可。
1 function checkIp($ip, $rule) 2 { 3 $rule_regexp = str_replace('.*', 'a', $rule);//将.*临时替换成别的符号(.和*都是正则中有特殊含义的符号) 4 $rule_regexp = preg_quote($rule_regexp, '/');//向规则字符串中增加转义,避免字符串中有其他特殊字符影响正则匹配,非必要语句本例可以忽略 5 $rule_regexp = str_replace('a','\.\d{1,3}', $rule_regexp);//将临时符号替换成正则表达式 6 if(preg_match('/^' . $rule_regexp . '$/', $ip)){ 7 return 1;//匹配 8 }else{ 9 return 0;//不匹配 10 } 11 } 12 13 $arr = getWhiteIps('white_ips.conf'); 14 $ip = '192.168.1.'; 15 $allow = 0; 16 foreach ($arr as $rule) { 17 if(checkIp($ip, $rule)){ 18 $allow = 1;//找到一个排配则标记白名单,然后结束循环 19 break; 20 } 21 } 22 echo $allow;
这种有范围的验证,稍微复杂一点,需要逐一比对判断。利用正则匹配IP后,结束循环。