ip白名单或者黑名单,目的是为了达到一种受限访问,希望在名单内用户可以访问,就把名单叫白名单;希望在名单内用户拒绝访问,就是黑名单。无论我们希望使用哪种名单方式,实现方式都一样。
在nginx下我们通常会考虑用nginx+lua的方式来实现,它很优雅速度快。确实,这是一种方案,我也做过这种方案的研究。但我觉的它不够灵活,我选择在应用程序中来实现名单机制。
主要思路:用户->获取ip->redis取出名单库->比对->处理
代码Github库:https://github.com/jacoobwang…
控制访问
<?php
isAccess();
/**
* 检测是否在白名单内,否则拒绝访问
*
* @return void
*/
function isAccess(){
$ip = getRemoteIp();
if(!empty($ip)) {
$inst = new Redis();
$inst->connect('127.0.0.1', 6379);
$ip_white_list = $inst->sMembers('ip_blacklist');
if(!in_array($ip, $ip_white_list)) {
echo '<h1 align=center>HTTP/1.1 403 Forbidden</h1>';
header('HTTP/1.1 403 Forbidden');
}
}
}
/**
* 获取用户的IP
*
* @return void
*/
function getRemoteIp(){
if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}elseif(isset($_SERVER['HTTP_CLIENT_IP'])){
$ip = $_SERVER['HTTP_CLIENT_IP'];
}elseif(getenv('HTTP_X_FORWARDED_FOR')){
$ip = getenv('HTTP_X_FORWARED_FOR');
}elseif(getenv('HTTP_CLIENT_IP')){
$ip = getenv('HTTP_CLIENT_IP');
}elseif($_SERVER['REMOTE_ADDR']){
$ip = $_SERVER['REMOTE_ADDR'];
}
else{
$ip = null;
}
return $ip;
}
动态配置页面
<?php
$inst = new Redis();
$inst->connect('127.0.0.1', 6379);
$ip = $inst->sMembers('ip_blacklist');
$li = '';
foreach($ip as $val) {
$li .= '<li><span>'.$val.'</span> <a data="'.$val.'" class="js_del" href="javascript:void(0)">delete</a></li>';
}
?>
<html>
<head>
<style>
ul,li {
list-style: none;
}
ul {
margin: 0;
padding: 0;
}
li {
padding: 5px;
padding-top:0;
}
</style>
</head>
<body>
<ul id="ipList">
<?php echo $li;?>
</ul>
<input type="text" name="ip_text" />
<button id="submit">add</button>
</body>
<script src="https://cdn.bootcss.com/jquery/3.2.0/jquery.js"></script>
<script>
$(function(){
// 删除
$('#ipList').on('click','.js_del',function(){
var _this = this,
ip_text = $(this).attr('data');
$.ajax({
url: 'http://localhost:6699/ip-white-php/ip.php',
method: 'POST',
data: 'type=delete&ip='+ip_text,
success: function(res){
if(res == 1){
alert('success');
$(_this).parent().remove();
} else {
alert('failed');
}
}
})
})
// 添加
$('#submit').click(function(){
var ip_text = $("input[type=text]").val(),
re = /^\d{2,3}.\d{2,3}.\d{2,3}.\d{1,3}$/;
if (!re.test(ip_text)) {
alert('您输入的IP格式不对');
return;
}
$.ajax({
url: 'http://localhost:6699/ip-white-php/ip.php',
method: 'POST',
data: 'type=add&ip='+ip_text,
success: function(res){
if(res == 1){
alert('success');
$('#ipList').append('<li><span>'+ip_text+'</span> <a data="'+ip_text+'" class="js_del" href="javascript:void(0)">delete</a></li>')
} else {
alert('failed');
}
}
})
})
})
</script>
</html>
配置页面接口
<?php
$inst = new Redis();
$inst->connect('127.0.0.1', 6379);
$type = isset($_POST['type']) ? $_POST['type'] : '';
$ip = isset($_POST['ip']) ? $_POST['ip'] : '';
if(!empty($ip)){
$isExist = $inst->sIsMember('ip_blacklist',$ip);
if($isExist) {
if($type == 'delete'){
// delete
$rs = $inst->sRemove('ip_blacklist',$ip);
echo $rs;
}
} else {
if($type == 'add'){
if(preg_match('/^\d{2,3}.\d{2,3}.\d{2,3}.\d{1,3}$/',$ip)) {
$rs = $inst->sAdd('ip_blacklist',$ip);
echo $rs;
} else {
echo 2;
}
}
}
}