news 2026/3/30 12:13:44

php JWT 使用全攻略(firebase/php-jwt 实践笔记)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
php JWT 使用全攻略(firebase/php-jwt 实践笔记)

一、前置准备

1. 安装库

  • 使用 Composer 安装 firebase/php-jwt 是使用该库的前提。
composer require firebase/php-jwt

2. 核心类与方法

  • 核心类:Firebase\JWT\JWT(所有操作围绕此类展开)
  • 核心静态方法
    • JWT::encode():生成 JWT 令牌
    • JWT::decode():验证并解析 JWT 令牌
  • 异常类:如 Firebase\JWT\ExpiredException、Firebase\JWT\SignatureInvalidException,用于捕获验证过程中的异常

二、核心参数说明

1.JWT::encode()方法(生成 JWT)

方法签名:
public static function encode( array $payload, string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $key, string $alg = 'HS256', string $keyId = null, array $head = null ): string
参数详解:

参数名

类型

必选

说明

$payload

数组

JWT 的载荷,存储业务数据(如用户ID、过期时间),建议包含注册声明

$key

字符串/加密资源等

加密密钥:
1. 对称加密(HS256):自定义字符串密钥
2. 非对称加密(RS256):使用私钥(.pem文件内容)

$alg

字符串

加密算法,默认HS256

。常用:
- 对称:HS256、HS384、HS512
- 非对称:RS256、RS384、RS512

$keyId

字符串

密钥 ID,多密钥场景下标识当前密钥,写入 JWT 头部(kid字段)

$head

数组

自定义 JWT 头部信息,合并默认头部(含alg,typ)

常用注册声明(推荐在$payload使用):
  • iss(issuer):签发者(如网站域名)
  • aud(audience):接收者(如 API 域名)
  • sub(subject):主题(如用户唯一标识)
  • exp(expiration time):过期时间(Unix 时间戳,必填
  • nbf(not before):生效时间(Unix 时间戳)
  • iat(issued at):签发时间(Unix 时间戳)
  • jti(JWT ID):令牌唯一标识(防重放)

2.JWT::decode()方法(验证并解析 JWT)

方法签名:
public static function decode( string $jwt, string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate|JWKSet $key, array $allowedAlgs = ['HS256'] ): stdClass
参数详解:

参数名

类型

必选

说明

$jwt

字符串

待验证的 JWT 令牌(三段式字符串,用.分隔)

$key

字符串/加密资源等

验证密钥:
1. 对称加密:与生成时相同的字符串密钥
2. 非对称加密:公钥(.pem文件内容)

$allowedAlgs

数组

允许的加密算法列表,默认['HS256'],需与生成时一致,防止算法伪造攻击

返回值:验证通过返回 stdClass 对象,包含 $payload 所有数据(可通过 -> 访问属性)。

三、实际使用示例

示例 1:对称加密(HS256,简单常用)

适合单体应用、前后端分离(密钥仅服务端保管)场景。
主要流程:生成 JWT → 验证 JWT → 捕获异常
<?php // 1. 引入 Composer 自动加载 require_once __DIR__ . '/vendor/autoload.php'; // 2. 导入核心类和异常类 use Firebase\JWT\JWT; use Firebase\JWT\ExpiredException; use Firebase\JWT\SignatureInvalidException; use UnexpectedValueException; // 3. 配置参数 const SECRET_KEY = 'your-very-strong-secret-key-321-keep-it-safe'; const ALGORITHM = 'HS256'; // 生成 JWT 令牌 function generateJwtToken(int $userId): string { $payload = [ 'iss' => 'https://example.com', 'aud' => 'https://api.example.com', 'sub' => (string)$userId, 'iat' => time(), 'exp' => time() + 3600, 'jti' => uniqid('jwt_', true), 'username' => 'test_user', 'role' => 'admin' ]; return JWT::encode($payload, SECRET_KEY, ALGORITHM); } // 验证并解析 JWT 令牌 function verifyJwtToken(string $jwt): ?stdClass { try { $decoded = JWT::decode($jwt, SECRET_KEY, [ALGORITHM]); return $decoded; } catch (ExpiredException $e) { echo "错误:JWT 令牌已过期 - " . $e->getMessage() . PHP_EOL; } catch (SignatureInvalidException $e) { echo "错误:JWT 签名无效 - " . $e->getMessage() . PHP_EOL; } catch (UnexpectedValueException $e) { echo "错误:JWT 格式无效 - " . $e->getMessage() . PHP_EOL; } catch (Exception $e) { echo "错误:JWT 验证失败 - " . $e->getMessage() . PHP_EOL; } return null; } // 测试 $jwtToken = generateJwtToken(10086); echo "生成的 JWT 令牌:" . PHP_EOL . $jwtToken . PHP_EOL . PHP_EOL; $decodedData = verifyJwtToken($jwtToken); if ($decodedData) { echo "JWT 验证通过,解析的数据:" . PHP_EOL; echo "用户ID:" . $decodedData->sub . PHP_EOL; echo "用户名:" . $decodedData->username . PHP_EOL; echo "过期时间:" . date('Y-m-d H:i:s', $decodedData->exp) . PHP_EOL; }

示例 2:非对称加密(RS256,适合分布式系统)

适合多服务协作(如微服务),私钥签发,公钥验签,安全性更高。
步骤 1:生成 RSA 密钥对(终端命令)
# 生成私钥(2048 位,无密码) openssl genrsa -out private.pem 2048 # 从私钥生成公钥 openssl rsa -in private.pem -pubout -out public.pem
步骤 2:PHP 代码实现
<?php require_once __DIR__ . '/vendor/autoload.php'; use Firebase\JWT\JWT; use Firebase\JWT\ExpiredException; use Firebase\JWT\SignatureInvalidException; use UnexpectedValueException; const PRIVATE_KEY_PATH = __DIR__ . '/private.pem'; const PUBLIC_KEY_PATH = __DIR__ . '/public.pem'; const ALGORITHM = 'RS256'; $privateKey = file_get_contents(PRIVATE_KEY_PATH); $publicKey = file_get_contents(PUBLIC_KEY_PATH); // 私钥生成 JWT function generateRsaJwtToken(int $userId, string $privateKey): string { $payload = [ 'iss' => 'https://example.com', 'sub' => (string)$userId, 'iat' => time(), 'exp' => time() + 3600, 'username' => 'test_user_rsa' ]; return JWT::encode($payload, $privateKey, ALGORITHM); } // 公钥验证 JWT function verifyRsaJwtToken(string $jwt, string $publicKey): ?stdClass { try { $decoded = JWT::decode($jwt, $publicKey, [ALGORITHM]); return $decoded; } catch (ExpiredException $e) { echo "错误:JWT 令牌已过期 - " . $e->getMessage() . PHP_EOL; } catch (SignatureInvalidException $e) { echo "错误:JWT 签名无效 - " . $e->getMessage() . PHP_EOL; } catch (UnexpectedValueException $e) { echo "错误:JWT 格式无效 - " . $e->getMessage() . PHP_EOL; } catch (Exception $e) { echo "错误:JWT 验证失败 - " . $e->getMessage() . PHP_EOL; } return null; } // 测试 $jwtToken = generateRsaJwtToken(10087, $privateKey); echo "生成的 RSA JWT 令牌:" . PHP_EOL . $jwtToken . PHP_EOL . PHP_EOL; $decodedData = verifyRsaJwtToken($jwtToken, $publicKey); if ($decodedData) { echo "RSA JWT 验证通过,解析的数据:" . PHP_EOL; echo "用户ID:" . $decodedData->sub . PHP_EOL; echo "用户名:" . $decodedData->username . PHP_EOL; }

四、总结汇总

核心要点回顾

  1. 核心操作:JWT::encode() 生成令牌,JWT::decode() 验证解析令牌,依赖密钥及算法。
  2. 参数核心
  • 生成:$payload 必须含 exp,$key 按算法类型选择(对称=字符串,非对称=私钥)
  • 验证:$key 与生成匹配(对称=相同字符串,非对称=公钥),$allowedAlgs 包含生成算法
  1. 安全性注意
  • 不在 $payload 存储敏感信息(JWT 可被解码)
  • 严格保管对称密钥/私钥,公钥可公开
  • 捕获验证异常,区分异常类型做针对性处理
  1. 常用场景
  • 对称加密(HS256):单体应用、前后端分离身份认证
  • 非对称加密(RS256):微服务、跨系统协作

常见问题提醒

  1. ExpiredException:检查 exp 是否为 Unix 时间戳且大于当前时间,注意服务器时区
  2. SignatureInvalidException:检查密钥匹配、算法一致、令牌未被篡改
  3. 令牌过长:$payload 仅存必要业务标识

总结

  • firebase/php-jwt 以 JWT::encode()(生成)和 JWT::decode()(验证)为核心,安全性依赖密钥和算法。
  • 对称加密(HS256)简单高效,适合单服务;非对称加密(RS256)安全性高,适合分布式系统。
  • 生成 JWT 必须设置 exp 过期时间,验证时需捕获各类异常,且避免载荷存储敏感信息。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/28 3:54:58

MindSpore 进阶:在 Ascend NPU 上构建高效的自定义训练步 (TrainOneStep)

在深度学习的实际工程落地中&#xff0c;这时候往往发现官方封装好的 Model.train接口虽然方便&#xff0c;但在处理一些复杂的算法逻辑&#xff08;如 GAN、强化学习或这就需要我们在 Ascend NPU 上进行自定义训练循环的构建。本文将剥离繁复的理论&#xff0c;直接通过代码演…

作者头像 李华
网站建设 2026/3/26 12:29:29

fscanf用法详解:C语言从文件读取格式化数据

在C语言文件操作中&#xff0c;fscanf函数是实现从文件读取格式化数据的关键工具。它允许你像使用scanf从键盘读取数据一样&#xff0c;从指定的文件流中按照特定格式提取信息。正确掌握fscanf的用法&#xff0c;能极大提升处理文本配置、日志分析等任务的效率。下面我将从几个…

作者头像 李华
网站建设 2026/3/28 4:36:54

树莓派3B GPIO入门教程:引脚详解与使用指南

树莓派3B的GPIO接口是其最强大也最常用的功能之一&#xff0c;它让这台微型电脑能够与现实世界的电子元件互动&#xff0c;从而完成自动化控制、数据采集等多种任务。对于电子爱好者和开发者来说&#xff0c;掌握GPIO的使用是解锁树莓派潜力的关键一步。 树莓派3b GPIO是什么 …

作者头像 李华
网站建设 2026/3/22 15:00:54

3.23 Helm包管理实战:复杂应用模板化部署完整教程

3.23 Helm包管理实战:复杂应用模板化部署完整教程 引言 Helm是Kubernetes的包管理工具,通过Chart可以模板化部署复杂应用。本文将详细介绍Helm的使用方法,包括Chart创建、模板编写、依赖管理等。 一、Helm概述 1.1 Helm的作用 应用打包 模板化部署 版本管理 依赖管理 1.…

作者头像 李华
网站建设 2026/3/24 2:30:08

本土化突围:Gitee如何构筑企业级研发协作的护城河

本土化突围&#xff1a;Gitee如何构筑企业级研发协作的护城河 中国企业服务市场正在经历一场静默而深刻的变革。当Zoom、Slack等国际协同工具在中国市场遭遇水土不服时&#xff0c;一批本土化企业服务产品正通过深度适配中国企业的协作场景快速崛起。在研发协作领域&#xff0c…

作者头像 李华