php jwt redis实现
PHP 中使用 JWT 和 Redis 实现认证
环境准备
确保已安装 PHP 7.4+、Redis 扩展及 firebase/php-jwt 库。通过 Composer 安装 JWT 库:
composer require firebase/php-jwt
生成 JWT Token
使用 firebase/php-jwt 生成包含用户 ID 和过期时间的 Token。密钥需保密存储:
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
$key = 'your-secret-key';
$payload = [
'iss' => 'your-issuer',
'aud' => 'your-audience',
'iat' => time(),
'exp' => time() + 3600, // 1小时过期
'user_id' => 123
];
$token = JWT::encode($payload, $key, 'HS256');
Redis 存储 Token 将生成的 Token 存入 Redis 并设置过期时间,确保与 JWT 过期时间一致:
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->setex('user_token:123', 3600, $token); // 键格式为 user_token:{user_id}
验证 Token 从请求头获取 Token,验证其有效性并检查 Redis 是否存在:
$authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
if (preg_match('/Bearer\s(\S+)/', $authHeader, $matches)) {
$token = $matches[1];
try {
$decoded = JWT::decode($token, new Key($key, 'HS256'));
$user_id = $decoded->user_id;
// 检查 Redis 中是否存在该 Token
if ($redis->get("user_token:$user_id") !== $token) {
throw new Exception("Token invalid or expired");
}
echo "验证成功,用户ID: " . $user_id;
} catch (Exception $e) {
http_response_code(401);
echo "验证失败: " . $e->getMessage();
}
}
注销 Token 用户登出时从 Redis 删除 Token:
$redis->del('user_token:123');
自动续期 在每次验证 Token 时,若剩余有效期不足,可重新生成并更新 Redis:
$remainingTime = $decoded->exp - time();
if ($remainingTime < 1800) { // 剩余30分钟时续期
$newPayload = array_merge((array)$decoded, ['exp' => time() + 3600]);
$newToken = JWT::encode($newPayload, $key, 'HS256');
$redis->setex("user_token:$user_id", 3600, $newToken);
header('Authorization: Bearer ' . $newToken);
}
注意事项
- 密钥需足够复杂并定期更换。
- 生产环境建议使用 HTTPS 传输 Token。
- Redis 需配置持久化以防止数据丢失。
- 考虑使用连接池管理 Redis 连接以提高性能。







