微服务架构概述
在当今的云原生时代,微服务架构已成为构建复杂应用的主流选择。与传统的单体架构不同,微服务将应用拆分为多个小型、独立的服务,每个服务专注于特定的业务功能。本文将深入探讨如何使用PHP生态构建一个完整的分布式用户认证微服务系统。
系统架构设计
我们的认证系统包含以下核心组件:
- API网关:所有请求的入口,负责路由和认证
- 用户服务:处理用户注册、资料管理
- 认证服务:专门处理登录、令牌发放
- Redis缓存:存储会话和令牌数据
- MySQL数据库:持久化存储用户信息
技术栈选择
Lumen (微框架) - 用于构建轻量级服务
JWT (JSON Web Tokens) - 无状态认证
Redis - 缓存和会话存储
MySQL - 数据持久化
Docker - 容器化部署
Composer - 依赖管理
认证服务实现
1. JWT令牌生成器
<?php
class JWTGenerator {
private $secretKey;
private $algorithm = 'HS256';
public function __construct($secretKey) {
$this->secretKey = $secretKey;
}
public function generateToken($payload) {
$header = $this->base64UrlEncode(json_encode([
'alg' => $this->algorithm,
'typ' => 'JWT'
]));
$payload['iat'] = time();
$payload['exp'] = time() + (60 * 60 * 24); // 24小时过期
$payload = $this->base64UrlEncode(json_encode($payload));
$signature = $this->base64UrlEncode(
hash_hmac('sha256', "$header.$payload", $this->secretKey, true)
);
return "$header.$payload.$signature";
}
public function validateToken($token) {
$parts = explode('.', $token);
if (count($parts) !== 3) {
return false;
}
list($header, $payload, $signature) = $parts;
$validSignature = $this->base64UrlEncode(
hash_hmac('sha256', "$header.$payload", $this->secretKey, true)
);
if ($signature !== $validSignature) {
return false;
}
$payloadData = json_decode($this->base64UrlDecode($payload), true);
if (isset($payloadData['exp']) && $payloadData['exp'] < time()) {
return false;
}
return $payloadData;
}
private function base64UrlEncode($data) {
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
private function base64UrlDecode($data) {
return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
}
}
?>
2. 用户服务实现
<?php
class UserService {
private $db;
private $redis;
public function __construct($db, $redis) {
$this->db = $db;
$this->redis = $redis;
}
public function register($email, $password, $userData = []) {
// 验证邮箱唯一性
if ($this->findUserByEmail($email)) {
throw new Exception('邮箱已被注册');
}
// 密码加密
$hashedPassword = password_hash($password, PASSWORD_BCRYPT);
// 创建用户
$userId = $this->createUser([
'email' => $email,
'password' => $hashedPassword,
'name' => $userData['name'] ?? '',
'created_at' => date('Y-m-d H:i:s')
]);
// 清除相关缓存
$this->redis->del("user:{$userId}");
return $userId;
}
public function authenticate($email, $password) {
$user = $this->findUserByEmail($email);
if (!$user || !password_verify($password, $user['password'])) {
throw new Exception('邮箱或密码错误');
}
// 更新最后登录时间
$this->updateLastLogin($user['id']);
return [
'id' => $user['id'],
'email' => $user['email'],
'name' => $user['name']
];
}
private function findUserByEmail($email) {
// 先尝试从缓存获取
$cachedUser = $this->redis->get("user:email:{$email}");
if ($cachedUser) {
return json_decode($cachedUser, true);
}
// 数据库查询
$stmt = $this->db->prepare("SELECT * FROM users WHERE email = ?");
$stmt->execute([$email]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if ($user) {
// 缓存用户信息
$this->redis->setex("user:email:{$email}", 3600, json_encode($user));
}
return $user;
}
}
?>
3. API网关中间件
<?php
class AuthMiddleware {
private $jwtGenerator;
private $excludedRoutes = ['/auth/login', '/auth/register'];
public function __construct($jwtGenerator) {
$this->jwtGenerator = $jwtGenerator;
}
public function handle($request) {
$path = $request->getPathInfo();
// 排除不需要认证的路由
if (in_array($path, $this->excludedRoutes)) {
return $request;
}
$token = $this->extractToken($request);
if (!$token) {
http_response_code(401);
echo json_encode(['error' => '未提供认证令牌']);
exit;
}
$payload = $this->jwtGenerator->validateToken($token);
if (!$payload) {
http_response_code(401);
echo json_encode(['error' => '无效或过期的令牌']);
exit;
}
// 将用户信息添加到请求中
$request->user = $payload;
return $request;
}
private function extractToken($request) {
$authHeader = $request->headers->get('Authorization');
if (preg_match('/Bearers+(.*)$/i', $authHeader, $matches)) {
return $matches[1];
}
return $request->query->get('token');
}
}
?>
4. Lumen认证控制器
<?php
class AuthController {
private $userService;
private $jwtGenerator;
public function __construct($userService, $jwtGenerator) {
$this->userService = $userService;
$this->jwtGenerator = $jwtGenerator;
}
public function register($request) {
try {
$data = $request->getJson();
$userId = $this->userService->register(
$data['email'],
$data['password'],
['name' => $data['name']]
);
return response()->json([
'success' => true,
'message' => '注册成功',
'user_id' => $userId
], 201);
} catch (Exception $e) {
return response()->json([
'success' => false,
'message' => $e->getMessage()
], 400);
}
}
public function login($request) {
try {
$data = $request->getJson();
$user = $this->userService->authenticate(
$data['email'],
$data['password']
);
$token = $this->jwtGenerator->generateToken([
'user_id' => $user['id'],
'email' => $user['email'],
'name' => $user['name']
]);
return response()->json([
'success' => true,
'token' => $token,
'user' => $user
]);
} catch (Exception $e) {
return response()->json([
'success' => false,
'message' => $e->getMessage()
], 401);
}
}
public function profile($request) {
return response()->json([
'success' => true,
'user' => $request->user
]);
}
}
?>
数据库设计
CREATE TABLE users (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
name VARCHAR(100),
last_login_at TIMESTAMP NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_email (email),
INDEX idx_created_at (created_at)
);
CREATE TABLE user_sessions (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT NOT NULL,
token_hash VARCHAR(255) NOT NULL,
expires_at TIMESTAMP NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
INDEX idx_token_hash (token_hash),
INDEX idx_expires_at (expires_at)
);
Docker容器化部署
Docker Compose配置
version: '3.8'
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./api:/var/www/html
depends_on:
- auth-service
- user-service
auth-service:
build: ./auth-service
volumes:
- ./auth-service:/var/www/html
environment:
- DB_HOST=mysql
- REDIS_HOST=redis
user-service:
build: ./user-service
volumes:
- ./user-service:/var/www/html
environment:
- DB_HOST=mysql
- REDIS_HOST=redis
mysql:
image: mysql:8.0
environment:
- MYSQL_ROOT_PASSWORD=secret
- MYSQL_DATABASE=auth_system
volumes:
- mysql_data:/var/lib/mysql
redis:
image: redis:alpine
ports:
- "6379:6379"
volumes:
mysql_data:
性能测试与优化
压力测试结果
# 使用Apache Bench进行测试
ab -n 1000 -c 100 http://localhost/auth/login
# 测试结果示例
Requests per second: 345.67 [#/sec]
Time per request: 28.912 [ms]
99% requests completed within 150ms
优化策略
- 连接池:数据库和Redis连接复用
- 缓存策略:多级缓存减少数据库查询
- 异步处理:日志记录等操作异步化
- 负载均衡:多实例部署提高可用性
安全最佳实践
- 密码安全:使用bcrypt加密,盐值随机生成
- 令牌安全:JWT设置合理过期时间,使用HTTPS传输
- 输入验证:严格验证所有用户输入
- SQL注入防护:使用预处理语句
- 速率限制:防止暴力破解攻击
监控与日志
<?php
class SystemLogger {
public static function logAuth($userId, $action, $ip) {
$logEntry = [
'timestamp' => date('c'),
'user_id' => $userId,
'action' => $action,
'ip' => $ip,
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? ''
];
// 写入文件或发送到日志服务
file_put_contents(
'/var/log/auth.log',
json_encode($logEntry) . "n",
FILE_APPEND
);
}
}
?>
总结
本文详细介绍了使用PHP构建分布式用户认证微服务系统的完整方案。通过采用微服务架构,我们将系统拆分为独立的服务组件,提高了系统的可维护性、可扩展性和容错能力。
关键收获:
- 微服务架构的设计原则和实现方法
- JWT无状态认证的安全实现
- Redis在分布式系统中的缓存应用
- Docker容器化部署的最佳实践
- 高并发系统的性能优化策略
这套系统为构建现代Web应用提供了可靠的认证基础,可以轻松扩展到更复杂的业务场景,为企业的数字化转型提供技术支撑。

