本文目录导读:

我来详细说明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集群存储
- 本地+远程双重验证
- 签名防篡改
- 限流保护
- 缓存优化
需要根据实际业务场景调整过期时间、缓存策略和验证逻辑。