PHP 怎么PHP 分布式授权

wen PHP项目 1

本文目录导读:

PHP 怎么PHP 分布式授权

  1. 核心架构设计
  2. Token生成与验证
  3. 客户端实现
  4. 分布式缓存方案
  5. API网关实现
  6. 使用示例
  7. 性能优化建议

我来详细说明PHP分布式授权系统的实现方案:

核心架构设计

授权服务器架构

// config/auth_server.php
return [
    'token_expire' => 3600,        // token过期时间
    'sign_key' => 'your_secret_key', // 签名密钥
    'redis_config' => [
        'host' => '127.0.0.1',
        'port' => 6379,
        'password' => '',
        'database' => 0
    ]
];

Token生成与验证

授权服务器端

<?php
// AuthServer.php
class AuthServer {
    private $redis;
    private $config;
    public function __construct($config) {
        $this->redis = new Redis();
        $this->redis->connect($config['redis_config']['host'], 
                              $config['redis_config']['port']);
        $this->config = $config;
    }
    // 生成授权Token
    public function generateToken($userId, $permissions = []) {
        $token = [
            'user_id' => $userId,
            'permissions' => $permissions,
            'expire' => time() + $this->config['token_expire'],
            'random' => bin2hex(random_bytes(16))
        ];
        // 签名
        $token['sign'] = $this->sign($token);
        // 存入Redis
        $this->redis->setex(
            "auth_token:{$token['user_id']}",
            $this->config['token_expire'],
            json_encode($token)
        );
        return base64_encode(json_encode($token));
    }
    // 验证Token
    public function validateToken($tokenString) {
        $token = json_decode(base64_decode($tokenString), true);
        // 验证签名
        if (!$this->verifySign($token)) {
            return false;
        }
        // 验证过期
        if ($token['expire'] < time()) {
            return false;
        }
        // 验证Redis中的会话
        $savedToken = $this->redis->get("auth_token:{$token['user_id']}");
        if (!$savedToken) {
            return false;
        }
        return $token;
    }
    // 签名
    private function sign($data) {
        return hash_hmac('sha256', 
            json_encode($data), 
            $this->config['sign_key']
        );
    }
    // 验证签名
    private function verifySign($token) {
        $sign = $token['sign'];
        unset($token['sign']);
        return $sign === $this->sign($token);
    }
}

客户端实现

客户端SDK

<?php
// AuthClient.php
class AuthClient {
    private $authServerUrl;
    private $appId;
    private $appSecret;
    private $localToken = null;
    public function __construct($config) {
        $this->authServerUrl = $config['auth_server_url'];
        $this->appId = $config['app_id'];
        $this->appSecret = $config['app_secret'];
    }
    // 获取授权
    public function authenticate($username, $password) {
        $response = $this->httpPost("{$this->authServerUrl}/auth", [
            'app_id' => $this->appId,
            'username' => $username,
            'password' => $password,
            'timestamp' => time(),
            'sign' => $this->generateSign([
                'username' => $username,
                'password' => $password,
                'timestamp' => time()
            ])
        ]);
        if ($response['code'] == 200) {
            $this->localToken = $response['token'];
            return true;
        }
        return false;
    }
    // 验证权限
    public function checkPermission($permission) {
        if (!$this->localToken) {
            return false;
        }
        // 本地验证
        $tokenData = $this->decodeToken($this->localToken);
        if (in_array($permission, $tokenData['permissions'])) {
            return true;
        }
        // 远程验证
        return $this->remoteValidate($permission);
    }
    // 远程验证
    private function remoteValidate($permission) {
        $response = $this->httpPost("{$this->authServerUrl}/validate", [
            'token' => $this->localToken,
            'permission' => $permission,
            'timestamp' => time(),
            'sign' => $this->generateSign([
                'token' => $this->localToken,
                'permission' => $permission,
                'timestamp' => time()
            ])
        ]);
        return $response['code'] == 200 && $response['allowed'];
    }
    // 签名生成
    private function generateSign($data) {
        ksort($data);
        $str = http_build_query($data) . $this->appSecret;
        return md5($str);
    }
}

分布式缓存方案

Redis集群配置

<?php
// RedisCluster.php
class RedisCluster {
    private static $instance = null;
    private $connections = [];
    public static function getInstance() {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    // 一致性哈希
    public function getConnection($key) {
        $hash = crc32($key);
        $nodeCount = count($this->connections);
        $nodeIndex = abs($hash) % $nodeCount;
        return $this->connections[$nodeIndex];
    }
    public function addNode($host, $port) {
        $this->connections[] = [
            'host' => $host,
            'port' => $port,
            'connection' => new Redis()
        ];
        $index = count($this->connections) - 1;
        $this->connections[$index]['connection']->connect($host, $port);
    }
}

API网关实现

网关中间件

<?php
// ApiGateway.php
class ApiGateway {
    private $authClient;
    private $rateLimiter;
    public function handle($request) {
        // 1. 限流检查
        if (!$this->rateLimiter->allowRequest($request->ip)) {
            return $this->response(429, 'Too Many Requests');
        }
        // 2. Token验证
        $token = $request->header('Authorization');
        if (!$token || !$this->authClient->validateToken($token)) {
            return $this->response(401, 'Unauthorized');
        }
        // 3. 权限检查
        if (!$this->authClient->checkPermission($request->path)) {
            return $this->response(403, 'Forbidden');
        }
        // 4. 转发请求
        return $this->forwardRequest($request);
    }
}

使用示例

完整授权流程

<?php
// Usage example
$config = [
    'auth_server_url' => 'http://auth-server.local',
    'app_id' => 'your_app_id',
    'app_secret' => 'your_app_secret',
    'redis_config' => [
        'host' => '127.0.0.1',
        'port' => 6379
    ]
];
$authClient = new AuthClient($config);
// 登录
if ($authClient->authenticate('username', 'password')) {
    echo "登录成功\n";
    // 检查权限
    if ($authClient->checkPermission('admin.access')) {
        echo "有管理员权限\n";
    } else {
        echo "无管理员权限\n";
    }
} else {
    echo "登录失败\n";
}

性能优化建议

缓存策略

// 本地缓存
$cache = new ArrayCache();
$cache->set('user_'.$userId, $permissions, 300); // 5分钟缓存
// 缓存击穿保护
if (($data = $cache->get($key)) === false) {
    if ($this->mutex->lock($key)) {
        $data = $this->loadFromDB($key);
        $cache->set($key, $data, 300);
        $this->mutex->unlock($key);
    } else {
        // 等待其他进程加载
        usleep(100000);
        $data = $cache->get($key);
    }
}

这个分布式授权系统支持:

  • Token无状态验证
  • Redis集群存储
  • 本地+远程双重验证
  • 签名防篡改
  • 限流保护
  • 缓存优化

需要根据实际业务场景调整过期时间、缓存策略和验证逻辑。

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