使用 firebase/php-jwt 库实现 jwt 登录鉴权,通过签发包含用户 id 和过期时间的 token 并在请求头中携带验证。token 过期刷新采用双 token 机制,即访问令牌(access token)短效、刷新令牌(refresh token)长效,利用 refresh token 换取新的 access token。

如何签发并验证 JWT Token
在 PHP 中实现 JWT 鉴权,核心是调用 JWT::encode() 生成签名 Token,并通过 JWT::decode() 解析验证。开发者需定义一个安全的密钥 $key,构建包含 iss(签发者)、sub(主题/用户ID)和 exp(过期时间)的载荷数组,设置算法为 HMAC SHA256。验证时,从 HTTP 请求头提取 Authorization: Bearer <token></token>,解码后检查 exp 是否大于当前时间戳,从而确认用户身份合法且 Token 未过期。

<?php
require_once 'vendor/autoload.php';
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
$key = "your_secret_key";
$user_id = 1001;
$now = time();
// 签发 Token:有效期 1 小时
$payload = [
"iss" => "http://example.org",
"sub" => $user_id,
"iat" => $now,
"exp" => $now + 3600
];
$jwt = JWT::encode($payload, $key, 'HS256');
echo "Generated Token:\n" . $jwt . "\n\n";
// 验证 Token
try {
$decoded = JWT::decode($jwt, new Key($key, 'HS256'));
echo "User ID: " . $decoded->sub . "\n";
echo "Valid until: " . date('Y-m-d H:i:s', $decoded->exp) . "\n";
} catch (Exception $e) {
echo "Invalid Token: " . $e->getMessage() . "\n";
}
?>
运行上述代码将输出签发的 Token 字符串,并在验证部分打印出解析后的用户 ID 和过期时间。若修改 Token 内容或密钥,验证将抛出异常,确保安全性。
立即学习“PHP免费学习笔记(深入)”;
如何实现 Token 过期自动刷新
Token 过期刷新依赖于 Refresh Token 机制,当 Access Token 失效时,客户端携带 Refresh Token 请求新的 Access Token。实现时,登录接口同时返回 Access Token(短效,如 15 分钟)和 Refresh Token(长效,如 7 天),并将 Refresh Token 存入数据库或缓存。刷新接口接收 Refresh Token,验证其有效性后,生成新的 Access Token 并可选地轮换 Refresh Token 以增强安全。此过程无需用户重新输入密码,实现无感续期。

<?php
// 模拟刷新流程
$refresh_token = "valid_refresh_token_string";
$stored_refresh = "valid_refresh_token_string"; // 假设从 DB 获取
if ($refresh_token === $stored_refresh) {
$new_payload = [
"iss" => "http://example.org",
"sub" => 1001,
"iat" => time(),
"exp" => time() + 900 // 新 Access Token 15 分钟有效
];
$new_access_token = JWT::encode($new_payload, $key, 'HS256');
echo "New Access Token: " . $new_access_token . "\n";
// 实际场景中应更新 DB 中的 Refresh Token
} else {
echo "Refresh Token Invalid\n";
}
?>
该代码演示了验证 Refresh Token 并签发新 Access Token 的过程。若 Refresh Token 不匹配,则拒绝刷新。实际应用中,建议每次刷新后轮换 Refresh Token 并更新存储,防止重放攻击。
基于程序中 exp 字段的具体问题
在程序中,exp 字段决定 Token 的有效期,若 exp 小于当前时间,JWT::decode() 会抛出 ExpiredException。开发者可通过比较 $decoded->exp 与 time() 提前判断 Token 状态,或在捕获异常后触发刷新逻辑。例如,在中间件中检查 exp,若即将过期(如剩余 5 分钟),可异步刷新 Token,提升用户体验。



















