OAuth 2.0 和 JWT 在 PHP 中的介绍
现代 Web 应用程序正越来越多地从传统的会话认证转向更灵活、可扩展的解决方案。两个关键协议——OAuth 2.0 和 JWT(JSON Web 令牌)——已成为 REST API、移动应用程序和微服务架构中授权的事实标准。在本文中,我们将通过实际示例,讲解如何使用现代库和最佳安全实践在 PHP 中实现 OAuth 2.0 和 JWT 授权。
您将学习如何配置授权服务器、签发和验证 JWT 令牌、组织刷新令牌的发放以及保护您的 API 端点。所有代码示例均可直接在您的项目中使用。
OAuth 2.0 协议基础
OAuth 2.0 是一种授权协议,允许应用程序在无需传递用户凭证的情况下,获取对用户资源的有限访问权限。在 PHP 应用程序的上下文中,OAuth 2.0 通常通过授权码授权(Authorization Code Grant)或针对自有服务的密码授权(Password Grant)来实现。
OAuth 2.0 中的关键角色
- 资源所有者 — 拥有数据的用户
- 客户端 — 请求访问的应用程序(例如您的 PHP 前端)
- 授权服务器 — 签发令牌的服务器
- 资源服务器 — 提供受保护资源的服务器(您的 API)
通过授权码授权获取令牌的流程
- 用户导航到授权页面
- 登录后,用户被重定向回应用程序,并附带一个临时授权码
- PHP 服务器用该授权码交换 access_token 和 refresh_token
- 所有后续对 API 的请求都包含
Authorization: Bearer <access_token>头
使用 firebase/php-jwt 库在 PHP 中实现 JWT
为了在 PHP 中处理 JWT,我们将使用流行的 firebase/php-jwt 库。通过 Composer 安装它:
composer require firebase/php-jwt生成 JWT 令牌
创建一个函数来签发带有有效载荷(claims)的访问令牌:
<?phpuse Firebase\\JWT\\JWT;use Firebase\\JWT\\Key;
function generateAccessToken(int $userId, string $email): string { $secretKey = 'your-256-bit-secret-key-here'; $issuedAt = time(); $expirationTime = $issuedAt + 3600; // 1 小时
$payload = [ 'iss' => 'pythonlib.ru', 'iat' => $issuedAt, 'exp' => $expirationTime, 'sub' => $userId, 'email' => $email, 'roles' => ['user'] ];
return JWT::encode($payload, $secretKey, 'HS256');}验证 JWT 令牌
每次请求受保护资源时验证令牌的真实性:
<?phpfunction validateAccessToken(string $token): ?object { $secretKey = 'your-256-bit-secret-key-here'; try { $decoded = JWT::decode($token, new Key($secretKey, 'HS256')); return $decoded; } catch (\\Exception $e) { // 令牌已过期、无效或签名不匹配 return null; }}用于验证 JWT 的中间件
一个简单的中间件示例,可与任何框架一起使用:
<?phpfunction authMiddleware(): ?object { $headers = getallheaders(); $authHeader = $headers['Authorization'] ?? '';
if (!preg_match('/Bearer\\s(\\S+)/', $authHeader, $matches)) { http_response_code(401); echo json_encode(['error' => '未提供令牌']); exit; }
$token = $matches[1]; $user = validateAccessToken($token);
if (!$user) { http_response_code(401);