PHP 怎么白名单开关

wen PHP项目 4

本文目录导读:

PHP 怎么白名单开关

  1. 方案一:基础开关常量(最简单)
  2. 方案二:URL 白名单(针对请求路径)
  3. 方案三:IP 白名单(针对请求来源)
  4. 方案四:用户角色权限白名单(针对逻辑权限)
  5. 方案五:配置文件化与缓存(大型项目推荐)
  6. 方案六:使用中间件(适合框架如 Laravel / ThinkPHP)

在 PHP 中实现白名单开关,通常是指只允许特定条件通过,其他条件一律拒绝,根据你的需求(是验证 URL、请求 IP、用户角色,还是某个功能模块的开关),有以下几种常见的实现方案:

基础开关常量(最简单)

如果你只想控制某个功能是否启用,直接定义一个全局常量或配置文件。

<?php
// config.php
// 设置为 true 则开启,false 则关闭
define('FEATURE_NEW_LOGIN_ENABLED', true);
define('APP_DEBUG', false);
?>
<?php
// 使用示例
if (FEATURE_NEW_LOGIN_ENABLED) {
    // 执行新逻辑
    echo "新登录逻辑已开启";
} else {
    echo "旧登录逻辑";
}
?>

URL 白名单(针对请求路径)

用于 Web 应用入口,只允许访问指定的路径,其他路径直接 404 或跳转。

<?php
$whitelist = [
    '/login',
    '/register',
    '/api/public',
    '/home'
];
// 获取当前访问的 URI(假设是 /login?name=xx)
$current_uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
if (!in_array($current_uri, $whitelist, true)) {
    http_response_code(404);
    exit('页面不存在'); // 或者跳到指定页面
}
// 通过验证,继续执行
echo "欢迎访问: " . $current_uri;
?>

IP 白名单(针对请求来源)

最典型的应用是后台管理接口,只允许特定 IP 访问。

<?php
function checkIpWhitelist(): bool {
    // 有效白名单
    $allowed_ips = [
        '127.0.0.1',       // 本机
        '192.168.1.100',   // 公司内网
        '10.0.0.0/8',      // 支持 CIDR
        '::1'              // IPv6 localhost
    ];
    $user_ip = $_SERVER['REMOTE_ADDR'] ?? '';
    foreach ($allowed_ips as $ip) {
        // 1. 精确匹配
        if ($ip === $user_ip) {
            return true;
        }
        // 2. CIDR 匹配
        if (strpos($ip, '/') !== false) {
            [$subnet, $prefix] = explode('/', $ip);
            if (isIpInSubnet($user_ip, $subnet, (int)$prefix)) {
                return true;
            }
        }
    }
    return false;
}
// 辅助函数:判断 IP 是否在子网内
function isIpInSubnet($ip, $subnet, $prefix) {
    if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) && 
        filter_var($subnet, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
        $ip_long = ip2long($ip);
        $subnet_long = ip2long($subnet);
        $mask = -1 << (32 - $prefix);
        $subnet_long &= $mask;
        return ($ip_long & $mask) === $subnet_long;
    }
    return false;
}
// 使用
if (!checkIpWhitelist()) {
    http_response_code(403); // 禁止访问
    exit('Access Denied');
}
?>

用户角色权限白名单(针对逻辑权限)

适用于后台系统,在 if 判断中加入角色验证。

<?php
function getUserRole() {
    // 假设从 Session 获取
    return $_SESSION['role'] ?? 'guest';
}
// 路由权限白名单映射
$role_whitelist = [
    'admin' => ['dashboard', 'settings', 'users', 'delete'],
    'editor' => ['dashboard', 'articles'],
    'guest' => ['login', 'index'],
];
$current_action = $_GET['action'] ?? 'index';
$user_role = getUserRole();
// 判断当前角色是否拥有这个 action 的权限
if (!isset($role_whitelist[$user_role]) || 
    !in_array($current_action, $role_whitelist[$user_role], true)) {
    http_response_code(403);
    exit('无权限执行此操作');
}
echo "允许执行: $current_action";
?>

配置文件化与缓存(大型项目推荐)

将白名单放到配置文件中(如 config/whitelist.php),并可以针对不同环境区分。

<?php
// config/whitelist.php
return [
    'api_keys' => ['abc123xyz', 'def456uvw'],
    'urls' => ['/open-api/v1/user'],
    'ips' => ['10.0.0.1', '172.16.0.0/16'],
    'features' => ['payment' => true, 'export' => false],
];
// 调用处
function checkWhitelist() {
    $whitelist = require __DIR__ . '/config/whitelist.php';
    // 检查 API Key
    $api_key = $_GET['token'] ?? null;
    if ($api_key && in_array($api_key, $whitelist['api_keys'], true)) {
        return true;
    }
    // 检查 URL
    $path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
    if (in_array($path, $whitelist['urls'], true)) {
        return true;
    }
    // 检查 IP
    $ip = $_SERVER['REMOTE_ADDR'];
    if (in_array($ip, $whitelist['ips'], true)) {
        return true;
    }
    return false;
}
?>

使用中间件(适合框架如 Laravel / ThinkPHP)

如果使用框架,通常框架自带“中间件”或“门卫”功能,以 Laravel 为例:

// app/Http/Middleware/CheckWhitelist.php
public function handle($request, Closure $next)
{
    $allowed_hosts = ['api.example.com', 'admin.example.com'];
    if (!in_array($request->getHost(), $allowed_hosts)) {
        abort(403, '非允许的主机');
    }
    return $next($request);
}

需求场景 推荐方案
功能是否开启 常量 + if/else
请求路径过滤 URL 白名单数组 + in_array
访问来源过滤 IP 白名单 + CIDR 匹配
用户权限管理 角色映射数组
大型系统 配置化 + 中间件

⚠️ 注意

  • 如果白名单数据较多,建议不要硬编码在函数里,而是放到配置文件或数据库中。
  • 涉及到安全(如 IP 限制),先拒绝后放行,默认拒绝任何未匹配项(deny by default)。
  • 在极端情况下(如防止暴力破解),可以结合缓存(Redis)做动态封禁。

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