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后,结束循环。

12-22 02:24