Download the PHP package kode/jwt without Composer
On this page you can find all versions of the php package kode/jwt. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Package jwt
Short Description 为现代 PHP 应用提供安全、灵活、高性能的 JWT 身份验证解决方案,支持单点登录(SSO)、多点登录、黑名单管理、自动续期、多平台适配,兼容 FPM、Swoole、RoadRunner 等运行环境。
License Apache-2.0
Informations about the package jwt
Kode JWT:一个健壮、全面、现代化的 PHP 8.3+ JWT 包
项目名称:
kode/jwt
当前版本:v1.15.0
目标:为现代 PHP 应用提供安全、灵活、高性能的 JWT 身份验证解决方案,支持单点登录(SSO)、多点登录、黑名单管理、自动续期、多平台适配、防重放攻击(Anti-Replay)、JWK 密钥管理、Token 客户端指纹绑定、JWKS 端点发布、Token Introspection、OIDC Discovery,兼容 FPM、Swoole、RoadRunner 等运行环境。
版本自述
本包版本可由类常量核对:Kode\Jwt\KodeJwt::VERSION,或调用 KodeJwt::version()(当前 1.15.0)。
composer.json 的 version 字段是 composer 侧的权威值,类常量是它的交叉核对副本——tests/VersionGuardTest.php 在两者不一致时直接失败,杜绝「tag 打了、常量忘改」的漂移。
📌 项目愿景
构建一个生产级、零侵入、高可扩展的 JWT 包,专为 PHP 8.3+ 设计,充分利用现代 PHP 特性(readonly class、类型化类常量、json_validate()、#[\Override] 属性、enum、联合类型、反射优化),并支持主流框架(Laravel、Symfony、ThinkPHP、Hyperf、EasySwoole 等)无缝接入。
可使用 kode 相关包或其他通用适合的包快速集成。
🚀 核心特性
| 特性 | 说明 |
|---|---|
| ✅ PHP 8.3+ 原生支持 | 使用 readonly class、类型化类常量(private const array FOO = [...])、json_validate()、#[\Override] 属性等 PHP 8.3+ 特性 |
| ✅ 多平台支持 | H5、PC、App、小程序(微信/支付宝/抖音)等,通过 platform 声明区分,是否启用平台,平台配置一致或单独配置 |
| ✅ 单点登录(SSO) | 同一用户在同一平台仅允许一个有效 Token,支持 Redis Lua 原子化踢出 |
| ✅ 多点登录(MLO) | 支持同一用户在多个设备同时登录 |
| ✅ Token 黑名单 | 支持主动注销、强制下线,基于 Redis 或内存存储(协程安全) |
| ✅ 自动续期(Refresh) | 支持滑动过期、固定刷新周期,防止频繁登录 |
| ✅ 多环境配置 | 支持 config/jwt.php 配置,兼容 Laravel、Hyperf 等框架 |
| ✅ 运行时兼容 | 支持 FPM、Swoole 多进程/协程、RoadRunner 多线程 |
| ✅ 类型安全 & 反射优化 | 使用 ReflectionClass + 缓存实现高性能依赖注入与配置解析 |
| ✅ 逆变/协变设计 | 接口设计遵循 LSP,支持泛型风格扩展(通过 PHPDoc + 命名规范) |
| ✅ 零框架依赖 | 可独立使用,也可通过适配器接入任意框架 |
| ✅ 事件驱动 | 提供 TokenIssued、TokenExpired、TokenRevoked 等事件钩子 |
| ✅ 审计日志 | 可选记录 Token 生成、使用、注销行为,使用通用日志包 |
| ✅ 加密算法可插拔 | 默认 HS256 / RS256,支持自定义签名器 |
| ✅ 防重放攻击(Anti-Replay) | 基于 Redis Nonce + 滑动窗口,杜绝 Token 被截获后重复使用 |
| ✅ 高熵 JTI | 32 字节(256 bit)密码学安全随机数,远高于 UUID v4 |
| ✅ 标准声明(iss/aud/sub) | 业务级强制校验,防止跨服务/跨租户混用 |
| ✅ 时钟漂移容忍 | 跨节点 NTP 偏差场景下,配置 clock_skew 即可容错 |
| ✅ Redis 原子化撤销 | Lua 脚本保证"黑名单 + SSO 映射 + 用户 Token 列表"三步原子性 |
| 🆕 v1.9 JWK 密钥管理(RFC 7517) | Jwk / JwkSet / KeyConverter / JwkFactory,支持 RSA / EC / oct 三种密钥类型,PEM ↔ JWK 互转,CSPRNG 安全密钥生成 |
| 🆕 v1.9 Token 客户端指纹绑定 | Fingerprint 组件将 Token 与客户端 UA + IP 前缀绑定,防止跨设备重放,内置可信内网 IP 白名单 |
| 🆕 v1.9 算法白名单强制校验 | 三层防御:永久禁用 none 算法 → 显式白名单 → 单算法严格匹配,杜绝算法混淆攻击 |
| 🆕 v1.9 PHP 8.3 readonly class | Jwk、JwkSet 等核心值对象使用 final readonly class,运行期不可变,防止密钥被篡改 |
| 🆕 v1.9 类型化类常量 | 使用 private const array SUPPORTED_KTY = [...] 等 PHP 8.3 类型化常量,强化类型安全 |
| 🆕 v1.10 JWKS 端点发布(RFC 7517 §5) | JwksPublisher 将 JWK Set 以标准 JSON 格式发布到 jwks_uri,自动剥离私钥,支持 ETag / If-None-Match 协商缓存 |
| 🆕 v1.10 Token Introspection(RFC 7662) | Introspector + IntrospectionResponse 提供标准 introspection 端点,资源服务器可查询 Token 当前状态 |
| 🆕 v1.10 OIDC Discovery(RFC 8414) | DiscoveryConfiguration + DiscoveryPublisher 发布授权服务器元数据,支持 /.well-known/openid-configuration |
| 🆕 v1.10 Scope 值对象与声明检查器 | Scope 不可变集合(has/hasAny/hasAll/intersect/diff),ClaimInspector 链式校验 issuer/audience/scope/time window |
| 🆕 v1.10 TokenPolicy 策略对象 | 不可变策略值对象,链式配置(issuer/audience/platform/scope/custom),一次性 enforce() 完成 Token 校验 |
| 🆕 v1.11 完整 JWS 算法族(RFC 7518/8017/8037) | Signer 统一门面:HMAC + RSA-PSS(真 EMSA-PSS)+ ECDSA(R‖S 标准 raw)+ EdDSA(Ed25519) |
| 🆕 v1.11 cnf 确认声明(RFC 7800) | Confirmation 值对象,支持 jkt/jwk/jku/kid,绑定密钥指纹 |
| 🆕 v1.11 DPoP 持有证明(RFC 9449) | DPoPProofBuilder / DPoPValidator:内联公钥 JWK 证明,防 Token 重放/转发 |
| 🆕 v1.11 Token 撤销端点(RFC 7009) | RevocationHandler 将 jti 加入黑名单,被撤销 Token 立即失效 |
| 🆕 v1.11 JWK 指纹(RFC 7638) | Jwk::thumbprint() 跨语言一致指纹,支持 RSA/EC/OKP/oct;EC/OKP PEM↔JWK 互转 |
📁 项目结构(PSR-4)
🛠️ 安装方式
CLI 工具初始化
安装完成后,在你的项目根目录运行以下命令来生成配置文件和密钥:
CLI 命令详解
| 命令 | 说明 | 示例 |
|---|---|---|
jwt install 或 jwt i |
安装配置文件并生成密钥 | php jwt install |
jwt key 或 jwt k |
生成密钥对 | php jwt key rsa |
jwt help 或 jwt h |
显示帮助信息 | php jwt help |
install 命令选项
| 选项 | 说明 |
|---|---|
--config-only |
仅发布配置文件,不生成密钥 |
--key-only |
仅生成密钥,不发布配置文件 |
--force |
强制覆盖已存在的文件 |
--platform=<name> |
指定默认平台(默认: web) |
key 命令选项
| 参数 | 说明 |
|---|---|
rsa |
生成 RSA 密钥对(默认) |
hmac |
生成 HMAC 密钥 |
stdout |
输出到标准输出(而非文件) |
file |
保存到文件(默认) |
--force |
强制覆盖已存在的密钥文件 |
示例:
生成的文件结构
运行 php jwt install 后,会在你的项目目录中生成以下文件:
重要:请确保
storage/keys/目录不在版本控制中(添加到.gitignore),以保护密钥安全。
🧩 配置文件(config/jwt.php)
运行 php jwt install 后,会自动生成配置文件。以下是完整配置说明:
🔐 核心类设计(示例)
Token/Payload.php
Payload增强功能详解
Payload类现在支持更灵活的自定义数据处理和更健壮的方法实现:
1. 灵活的自定义数据处理
Payload类提供了两种方式来处理自定义数据:
使用create()静态方法(推荐)
使用fromArray()方法
2. 增强的方法实现
Payload类提供了丰富的方法来操作和检查Payload数据:
自定义数据操作方法
角色和权限检查方法
其他实用方法
Guard/SsoGuard.php(单点登录)
「同一 uid + 平台只允许一个有效会话」由 SsoGuard::isUnique() 在签发时执行,
存储能力按接口分两条路径(见 v1.8.1 的 SsoStorageInterface 能力探测):
两处 $ttl 一律取 ttl + refresh_ttl(access 与续期窗口的总寿命,至少 1 秒):
被踢令牌在续期窗口内仍可被拿去刷新,黑名单条目若只按默认 3600 秒过期,
令牌就会在窗口内「复活」(v1.13.0 修复)。
开关与语义(v1.13.0 起):
| 配置 | 默认 | 说明 |
|---|---|---|
single_login |
true |
false 显式关闭「再登录踢出旧会话」,同一用户同平台可并存多令牌;SSO 守卫的核心语义是踢出,默认保持踢出 |
platform |
null |
签发与校验都必须携带 platform 声明,否则 SSO 映射键无法对齐 |
撤销是「按 jti 拉黑 + 删映射」,不会主动通知旧客户端;旧客户端下一次请求收到
TokenBlacklistedException(HTTP 401)后需走重新登录流程。
Storage/RedisStorage.php(协程安全)
🧪 使用示例(Laravel / Hyperf)
1. 生成 Token
2. 验证 Token
3. 刷新 Token
刷新会作废旧 Token(按剩余寿命拉黑)并签发新 Token,其中:
uid / username / platform / roles / perms / custom原样继承;iss / sub / aud一并携带(v1.13.0 起)——这三项是身份上下文,丢了就会让配了expected_claims的调用方在刷新后的下一次authenticate()直接失败;iat / exp / jti重新生成;nonce随新jti一起轮换(沿用旧 nonce 会与防重放记录冲突)。
刷新能力受 refresh_enabled(默认 true)与 refresh_ttl 窗口约束,
窗口外或 Token::canRefresh() 为假时抛 JwtException('Token cannot be refreshed')。
4. 注销 Token(黑名单管理)
被「注销 / 封禁 / 撤销」的 Token 会将其 jti 写入黑名单,后续在 Guard 鉴权、Introspection、isTokenValid 中都会立即判定为失效。
上述方法均支持可选的
$guard参数(传null使用默认守卫),自动路由到该守卫对应的存储后端。
5. 使用便捷方法
⚠️
KodeJwt::builder()不可跨请求共享(Builder 是可变对象)KodeJwt::builder()每次调用都返回全新实例,因此以下两种用法都是安全的:切勿把
KodeJwt::builder()的返回值存为全局/静态单例并在多次签发间复用,否则会出现 claims 泄漏与前次 jti 碰撞。 生产环境签发更推荐KodeJwt::guard($g)->issue(new Payload(...)),由 Guard 内部管理独立实例。
// 获取用户的所有活跃Token $tokens = KodeJwt::getUserTokens('123', 'app');
// 强制注销用户的所有Token $count = KodeJwt::revokeUserTokens('123', 'app');
// 检查Token是否有效 $isValid = KodeJwt::isTokenValid($token);
// 获取Token详细信息 $info = KodeJwt::getTokenInfo($token); // 返回: ['uid' => 123, 'platform' => 'app', 'exp' => 1234567890, ...]
// 清理过期的Token $cleanedCount = KodeJwt::cleanExpired();
// 获取存储统计信息 $stats = KodeJwt::getStats(); // 返回: ['total' => 100, 'expired' => 20, 'active' => 80]
// 使用增强的Payload创建方法 // 1. 使用数组自定义数据 $payload = Payload::create( uid: 456, username: 'janedoe', platform: 'web', exp: time() + 86400, iat: time(), jti: uniqid('jwt'), roles: ['user'], perms: ['read', 'write'], customData: [ 'department' => 'Marketing', 'level' => 3, 'preferences' => [ 'theme' => 'dark', 'language' => 'zh-CN' ] ] );
// 2. 使用加密字符串自定义数据 $encryptedData = base64_encode(json_encode([ 'sensitive_info' => 'secret_data', 'timestamp' => time() ]));
$payload = Payload::create( uid: 789, username: 'bobsmith', platform: 'mobile', exp: time() + 86400, iat: time(), jti: uniqid('jwt'), customData: $encryptedData );
┌─────────────────────────────────────────────────────────┐ │ 防御层 1:永久禁用 "none" 算法 │ │ 即使配置允许,"none" 也直接拒绝 │ ├─────────────────────────────────────────────────────────┤ │ 防御层 2:显式白名单(allowed_algorithms 数组) │ │ 适用于密钥轮换、多算法并存场景 │ │ Token alg 必须命中白名单 │ ├─────────────────────────────────────────────────────────┤ │ 防御层 3:单算法严格匹配(algo 单值) │ │ 适用于单算法场景 │ │ Token alg 必须与配置 algo 严格相等 │ └─────────────────────────────────────────────────────────┘
攻击者构造:alg=HS256,用服务端 RS256 公钥当 HMAC 密钥签名 ↓ 防御层 3 触发:Token alg=HS256 ≠ 配置 algo=RS256 → 拒绝 防御层 2 触发:HS256 不在 allowed_algorithms=[RS256, RS384] 中 → 拒绝
[客户端] ——A: 请求 (Token: eyJ...)→ [服务器] ↓ (Token 被截获) [攻击者] ——B: 重复使用 Token eyJ...→ [服务器]
[1] 解析 Token → 取出 jti、nonce [2] Redis EVAL "SET NX" → 首次消费返回 1,重放返回 0 [3] 命中重放 → 抛出 TokenReplayException json // phpstan.neon parameters: level: 12 paths:
- src
bash
生成 Token
php bin/jwt token generate --uid=123 --username=john --platform=web
验证 Token
php bin/jwt token verify --token=eyJ...
刷新 Token
php bin/jwt token refresh --token=eyJ...
注销 Token
php bin/jwt token invalidate --token=eyJ...
查看 Token 信息
php bin/jwt token info --token=eyJ... bash
安装依赖
composer require kode/jwt
发布配置文件(会生成 config/jwt.php)
php artisan jwt:install
生成密钥
php artisan jwt:key bash composer require kode/jwt bash composer require kode/jwt bash composer require kode/jwt yaml jwt: defaults: guard: api storage: redis guards: api: driver: sso storage: redis algo: RS256 public_key: '%kernel.project_dir%/var/keys/public.pem' private_key: '%kernel.project_dir%/var/keys/private.pem' ttl: 3600 refresh_ttl: 604800 storage: redis: host: 127.0.0.1 port: 6379 prefix: 'kode:jwt:' yaml services: Kode\Jwt\KodeJwt: class: Kode\Jwt\KodeJwt calls:
-
method: detectAndLoadConfig
App\Security\JwtAuthenticator: arguments: $jwtService: '@Kode\Jwt\KodeJwt' bash composer require kode/jwt bash php yii jwt/init bash composer require kode/jwt bash bin/cake jwt bash
下载并解压包后
php bin/jwt install --config-only php bin/jwt key rsa --force php KodeJwt::init([ 'guards' => [ 'api' => [ 'driver' => 'sso', 'storage' => 'custom', // 使用自定义存储 ], ], 'storage' => [ 'custom' => [ 'driver' => \App\Storage\CustomStorage::class, ], ], ]); php namespace App\Guard;
use Kode\Jwt\Contract\GuardInterface; use Kode\Jwt\Contract\StorageInterface; use Kode\Jwt\Token\Payload;
class CustomGuard implements GuardInterface { public function __construct( private StorageInterface $storage, private array $config ) {}
public function issue(Payload $payload): array
{
// 自定义签发逻辑
}
public function authenticate(string $token): Payload
{
// 自定义验证逻辑
}
public function refresh(string $token): array
{
// 自定义刷新逻辑
}
public function invalidate(string $token): bool
{
// 自定义注销逻辑
}
public function validateToken(string $token): bool
{
// 自定义验证逻辑
}
}
---
## 📦 依赖与兼容性
### 必需依赖
- PHP >= 8.3
- ext-json
- ext-openssl
### 可选依赖
- ext-redis:Redis 存储驱动
- ext-apcu:APCu 存储驱动
- ext-memcached:Memcached 存储驱动
- ext-pdo:数据库存储驱动
- ext-swoole:Swoole 协程支持
### 兼容环境
- PHP-FPM
- Swoole
- RoadRunner
- ReactPHP
- Amp
---All versions of jwt with dependencies
ext-json Version *
ext-openssl Version *