PHP 怎么PHP 黑名单鉴权

wen PHP项目 3

本文目录导读:

PHP 怎么PHP 黑名单鉴权

  1. 基于IP的黑名单鉴权
  2. 用户/账号黑名单
  3. 请求频率黑名单(防爬虫)
  4. 基于规则的黑名单
  5. 完整的黑名单中间件
  6. 数据库表结构
  7. 性能优化建议
  8. 实际使用示例

我来详细说明PHP中实现黑名单鉴权的几种方法:

基于IP的黑名单鉴权

简单IP黑名单

<?php
class IPBlacklist {
    private $blacklist = [
        '192.168.1.100',
        '10.0.0.50',
        '172.16.0.1'
    ];
    public function checkIP() {
        $userIP = $_SERVER['REMOTE_ADDR'];
        if (in_array($userIP, $this->blacklist)) {
            $this->denyAccess("IP被禁止访问");
            return false;
        }
        return true;
    }
    private function denyAccess($message) {
        http_response_code(403);
        echo json_encode(['error' => $message]);
        exit;
    }
}

IP范围黑名单(支持CIDR)

<?php
class IPBlacklistManager {
    private $blacklist = [
        '192.168.1.0/24',    // 整个C段
        '10.0.0.0/8',        // A类地址段
        '172.16.0.0/12'      // B类地址段
    ];
    public function isIpInRange($ip, $cidr) {
        list($subnet, $bits) = explode('/', $cidr);
        $ip = ip2long($ip);
        $subnet = ip2long($subnet);
        $mask = -1 << (32 - $bits);
        return ($ip & $mask) == ($subnet & $mask);
    }
    public function checkAccess() {
        $userIP = $_SERVER['REMOTE_ADDR'];
        foreach ($this->blacklist as $cidr) {
            if ($this->isIpInRange($userIP, $cidr)) {
                header('HTTP/1.0 403 Forbidden');
                exit('访问被拒绝');
            }
        }
    }
}

用户/账号黑名单

<?php
class UserBlacklist {
    private $db; // 数据库连接
    public function checkUser($userId) {
        // 从数据库获取黑名单
        $blacklist = $this->getBlacklistFromDB();
        if (in_array($userId, $blacklist)) {
            $this->logBlacklistAccess($userId);
            throw new Exception("用户已被禁止访问");
        }
    }
    private function getBlacklistFromDB() {
        // 示例:从数据库查询黑名单
        $stmt = $this->db->query("SELECT user_id FROM blacklist WHERE status = 1");
        return $stmt->fetchAll(PDO::FETCH_COLUMN);
    }
    public function addToBlacklist($userId, $reason) {
        $stmt = $this->db->prepare(
            "INSERT INTO blacklist (user_id, reason, created_at) 
             VALUES (?, ?, NOW())"
        );
        return $stmt->execute([$userId, $reason]);
    }
}

请求频率黑名单(防爬虫)

<?php
class RateLimitBlacklist {
    private $redis;
    private $maxRequests = 100;  // 每分钟最大请求数
    private $banDuration = 3600; // 封禁时长(秒)
    public function __construct() {
        $this->redis = new Redis();
        $this->redis->connect('127.0.0.1', 6379);
    }
    public function checkRateLimit() {
        $ip = $_SERVER['REMOTE_ADDR'];
        $key = "rate_limit:{$ip}";
        // 检查是否在黑名单中
        if ($this->redis->get("blacklist:{$ip}")) {
            $this->denyAccess("请求过于频繁,已被临时封禁");
        }
        // 增加请求计数
        $count = $this->redis->incr($key);
        if ($count === 1) {
            $this->redis->expire($key, 60); // 60秒过期
        }
        // 超过限制,加入黑名单
        if ($count > $this->maxRequests) {
            $this->redis->setex("blacklist:{$ip}", $this->banDuration, 1);
            $this->denyAccess("触发频率限制");
        }
    }
}

基于规则的黑名单

<?php
class RuleBasedBlacklist {
    private $rules = [
        'user_agent' => [
            'badbot',
            'scraper',
            'curl/7.0'
        ],
        'referer' => [
            'spam-site.com',
            'malware-site.net'
        ],
        'headers' => [
            'X-Forwarded-For' => ['malicious-ip']
        ]
    ];
    public function checkAllRules() {
        // 检查User-Agent
        if ($this->matchUserAgent()) {
            $this->blockRequest();
        }
        // 检查Referer
        if ($this->matchReferer()) {
            $this->blockRequest();
        }
        // 检查自定义头
        if ($this->matchHeaders()) {
            $this->blockRequest();
        }
    }
    private function matchUserAgent() {
        $ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
        foreach ($this->rules['user_agent'] as $pattern) {
            if (stripos($ua, $pattern) !== false) {
                return true;
            }
        }
        return false;
    }
}

完整的黑名单中间件

<?php
class BlacklistMiddleware {
    private $config;
    public function __construct() {
        $this->config = require 'blacklist_config.php';
    }
    public function handle($request) {
        // 1. IP检查
        if (!$this->checkIP($request->ip)) {
            return $this->deny();
        }
        // 2. User-Agent检查
        if (!$this->checkUserAgent($request->userAgent)) {
            return $this->deny();
        }
        // 3. 请求频率检查
        if (!$this->checkRateLimit($request->ip)) {
            return $this->deny();
        }
        // 4. Token/API Key检查
        if (!$this->checkToken($request->bearerToken)) {
            return $this->deny();
        }
        return true;
    }
    private function deny() {
        http_response_code(403);
        header('Content-Type: application/json');
        echo json_encode([
            'status' => false,
            'message' => 'Access Denied',
            'code' => 403
        ]);
        exit;
    }
}

数据库表结构

-- IP黑名单表
CREATE TABLE ip_blacklist (
    id INT PRIMARY KEY AUTO_INCREMENT,
    ip_address VARCHAR(45) NOT NULL,
    cidr VARCHAR(45),
    reason TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    expires_at TIMESTAMP NULL,
    INDEX idx_ip (ip_address)
);
-- 用户黑名单表
CREATE TABLE user_blacklist (
    id INT PRIMARY KEY AUTO_INCREMENT,
    user_id INT NOT NULL,
    reason TEXT,
    blacklist_type ENUM('temporary', 'permanent') DEFAULT 'temporary',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    expires_at TIMESTAMP NULL,
    INDEX idx_user (user_id)
);

性能优化建议

<?php
// 1. 使用缓存
class CachedBlacklist {
    private $cache;
    private $cacheTTL = 300; // 5分钟
    public function isBlacklisted($key) {
        $cacheKey = "blacklist_check:{$key}";
        // 从缓存获取
        if ($this->cache->has($cacheKey)) {
            return $this->cache->get($cacheKey);
        }
        // 实际检查逻辑
        $result = $this->checkBlacklist($key);
        // 写入缓存
        $this->cache->set($cacheKey, $result, $this->cacheTTL);
        return $result;
    }
}
// 2. 使用布隆过滤器(大规模黑名单)
class BloomFilterBlacklist {
    private $redis;
    private $bloomKey = 'ip_blacklist_bloom';
    public function __construct() {
        $this->redis = new Redis();
        $this->redis->connect('127.0.0.1', 6379);
    }
    public function isBlacklisted($ip) {
        // Redis 4.0+ 支持布隆过滤器
        return $this->redis->rawCommand('BF.EXISTS', $this->bloomKey, $ip);
    }
    public function addToBlacklist($ip) {
        return $this->redis->rawCommand('BF.ADD', $this->bloomKey, $ip);
    }
}

实际使用示例

<?php
// 启动黑名单检查
$blacklist = new BlacklistMiddleware();
$blacklist->handle($_SERVER);
// 继续执行正常逻辑
echo "欢迎访问";

注意事项:

  • 定期更新黑名单数据
  • 记录所有黑名单拦截日志
  • 提供白名单例外机制
  • 注意性能影响,必要时使用缓存
  • 考虑使用第三方服务(如Cloudflare)

根据具体需求选择合适的黑名单鉴权方式,可以是单一方式或组合使用。

抱歉,评论功能暂时关闭!