A JWT plugin compatible with webman, Laravel, ThinkPHP, and Hyperf. Suitable for distributed deployment, simple and fast installation.
erikwang2013/jwt-webman is a Laravel package for a jwt plugin compatible with webman, laravel, thinkphp, and hyperf. suitable for distributed deployment, simple and fast installation..
It currently has 1 GitHub stars and 576 downloads on Packagist (latest version v2.0.5).
Install it with composer require erikwang2013/jwt-webman.
Discover more Laravel packages by erikwang2013
or browse all Laravel packages to compare alternatives.
Last updated
一款兼容 webman、Laravel、ThinkPHP、Hyperf 的 JWT 认证插件。适用于分布式部署,安装简单快捷。
作者:艾瑞可erik
erikwang2013/jwt-webman 是一个 PHP 多框架 JWT 认证插件,核心基于 firebase/php-jwt 封装。
传统的 JWT 插件通常只绑定单一框架,在微服务或多项目架构中,不同框架之间需要各自对接不同的 JWT 实现,造成维护成本和认证逻辑不一致的风险。
本插件将核心逻辑与框架完全解耦,通过「一套核心 + 框架适配层」的架构,在 webman、Laravel、ThinkPHP、Hyperf 中提供一致的 API 体验。无论后端服务使用哪个框架,JWT 的编码、解码、刷新、黑名单逻辑完全一致,只需按照各框架的习惯方式进行配置和注入即可。
src/erik-jwt/
├── JWT.php ← 核心:令牌编解码、刷新、黑名单
├── JwtWrapper.php ← 核心:JWT 便捷封装,自动获取 Bearer Token
├── JWTFactory.php ← 核心:工厂类,根据配置创建实例
├── Config.php ← 核心:框架无关的配置容器
├── TokenStorageInterface.php ← 核心:存储抽象接口
├── RedisTokenStorage.php ← 黑名单存储:Redis(注入 callable 连接)
├── DatabaseTokenStorage.php ← 黑名单存储:数据库(注入 PDO 连接)
├── FileTokenStorage.php ← 黑名单存储:文件系统
├── MemcachedTokenStorage.php ← 黑名单存储:Memcached
├── RetryTokenStorage.php ← 装饰器:操作失败自动重试
├── JWTException.php ← 异常层级:过期/无效/黑名单/存储/配置/网络
│
├── Webman/ → Middleware
├── Laravel/ → ServiceProvider / Facade / Middleware / InstallCommand
├── ThinkPHP/ → Service / Facade / Middleware / InstallCommand
└── Hyperf/ → ConfigProvider / Middleware / AOP Aspect / #[JWT] Attribute
核心层不依赖任何框架 helper,所有外部依赖(配置、日志、数据库连接、Redis 连接)通过构造函数或工厂方法注入。每个框架的适配层负责从框架容器中获取这些依赖,组装后传入核心工厂。
composer require erikwang2013/jwt-webman
自 v1.1.0 起,提供了一个 JwtWrapper 便捷封装类,简化常见操作并支持自动从请求头获取 Token:
use Erikwang2013\Jwt\JwtWrapper;
$jwt = new JwtWrapper(JWTFactory::createFromConfig(
config('plugin.erikwang2013.jwt.jwt'),
null,
[
'redis' => fn() => \support\Redis::connection(),
'pdo' => \support\Db::connection()->getPdo(),
]
));
// 生成令牌
$token = $jwt->create(['user_id' => 1]);
// 生成令牌并指定过期时间(秒)
$token = $jwt->create(['user_id' => 1], 7200);
// 验证令牌,返回 payload 对象
$payload = $jwt->verify($token);
echo $payload->user_id;
// 仅验证不返回 payload
if ($jwt->validate($token)) { ... }
// 解码令牌(不校验有效性)
$data = $jwt->decode($token);
// 刷新令牌(自动从 Authorization 头获取当前 token)
$newToken = $jwt->refresh();
// 或手动传入 token 刷新
$newToken = $jwt->refresh($oldToken);
// 拉黑令牌
$jwt->blacklist($token);
// 检查令牌是否在黑名单
if ($jwt->isBlacklisted($token)) { ... }
适用所有框架,只需将 JWTFactory::createFromConfig() 替换为对应框架的创建方式即可。
composer require 后通过 webman 插件系统自动注册,无需手动配置。
配置文件: config/plugin/erikwang2013/jwt/jwt.php
基本用法:
use Erikwang2013\Jwt\JWTFactory;
$jwt = JWTFactory::createFromConfig(
config('plugin.erikwang2013.jwt.jwt'),
null,
[
'redis' => fn() => \support\Redis::connection(),
'pdo' => \support\Db::connection()->getPdo(),
]
);
// 生成令牌
$token = $jwt->encode(['user_id' => 1]);
// 验证令牌
$payload = $jwt->decode($token);
// 拉黑令牌
$jwt->blacklist($token);
中间件: 在 config/middleware.php 中注册:
return [
'' => [
\Erikwang2013\Jwt\Webman\Middleware::class,
],
];
在控制器中获取解析后的 payload:
$payload = $request->jwt_payload;
$userId = $payload['user_id'];
composer require 后通过 extra.laravel 自动发现 ServiceProvider。如果关闭了自动发现,手动在 config/app.php 中注册:
'providers' => [
Erikwang2013\Jwt\Laravel\JWTServiceProvider::class,
],
安装命令:
php artisan jwt:install
执行后会自动发布配置文件并生成 JWT_SECRET_KEY 写入 .env。
配置文件: config/jwt.php
门面方式:
use Erikwang2013\Jwt\Laravel\Facade as JWT;
$token = JWT::encode(['user_id' => 1]);
$payload = JWT::decode($token);
JWT::blacklist($token);
辅助函数:
$token = jwt()->encode(['user_id' => 1]);
依赖注入:
use Erikwang2013\Jwt\JWT;
public function __construct(JWT $jwt) {
$this->jwt = $jwt;
}
中间件:
// 路由中使用
Route::middleware('jwt')->group(function () {
Route::get('/api/user', [UserController::class, 'index']);
});
// 控制器中获取 payload
public function index(Request $request) {
$payload = $request->attributes->get('jwt_payload');
$userId = $payload['user_id'];
}
手动发布配置:
php artisan vendor:publish --tag=jwt-config
composer require 后在 app/service.php 中注册服务:
return [
\Erikwang2013\Jwt\ThinkPHP\JWTService::class,
];
安装命令:
php think jwt:install
配置文件: config/jwt.php
门面方式:
use Erikwang2013\Jwt\ThinkPHP\JWT;
$token = JWT::encode(['user_id' => 1]);
$payload = JWT::decode($token);
辅助函数:
$token = jwt()->encode(['user_id' => 1]);
中间件:
// 路由中使用
Route::group(function () {
Route::get('/api/user', 'UserController@index');
})->middleware('jwt');
// 控制器中获取 payload
public function index(Request $request) {
$payload = $request->jwt_payload;
$userId = $payload['user_id'];
}
composer require 后在 config/autoload/dependencies.php 中注册 ConfigProvider:
return [
\Erikwang2013\Jwt\Hyperf\ConfigProvider::class,
];
安装命令:
php bin/hyperf.php jwt:install
配置文件: config/autoload/jwt.php
依赖注入:
use Erikwang2013\Jwt\JWT;
use Hyperf\Di\Annotation\Inject;
class UserController {
#[Inject]
protected JWT $jwt;
public function index() {
$token = $this->jwt->encode(['user_id' => 1]);
$payload = $this->jwt->decode($token);
}
}
中间件: ConfigProvider 已自动注册,在 config/autoload/middlewares.php 中配置即可。
AOP 注解方式(可选):
use Erikwang2013\Jwt\Hyperf\JWT as JWTAuth;
class UserController {
#[JWTAuth]
public function index() {
// 方法执行前自动校验 JWT
}
}
return [
// 签名密钥,至少16字符
'secret_key' => env('JWT_SECRET_KEY', ''),
// 签名算法:HS256 / HS384 / HS512 / RS256
'algorithm' => env('JWT_ALGORITHM', 'HS256'),
// 签发者标识
'issuer' => env('JWT_ISSUER', ''),
// 受众标识
'audience' => env('JWT_AUDIENCE', ''),
// 时间容差(秒),用于处理服务器时钟偏差
'leeway' => (int) env('JWT_LEEWAY', 0),
// 默认令牌过期时间(秒)
'default_expire' => (int) env('JWT_DEFAULT_EXPIRE', 3600),
// 刷新令牌过期时间(秒)
'refresh_expire' => (int) env('JWT_REFRESH_EXPIRE', 7200),
// 黑名单存储配置
'storage' => [
// 存储类型:file / redis / database / memcached
'type' => env('JWT_STORAGE_TYPE', 'file'),
// 缓存键前缀
'prefix' => env('JWT_STORAGE_PREFIX', 'jwt_blacklist:'),
// Redis 数据库编号
'database' => (int) env('JWT_STORAGE_DATABASE', 0),
],
// 高级配置
'advanced' => [
// 操作失败重试次数
'retry_attempts' => (int) env('JWT_ADVANCED_RETRY_ATTEMPTS', 3),
// 重试延迟(毫秒)
'retry_delay' => (int) env('JWT_ADVANCED_RETRY_DELAY', 100),
// 是否自动清理过期条目
'auto_cleanup' => filter_var(env('JWT_AUTO_CLEANUP', false), FILTER_VALIDATE_BOOLEAN),
// 自动清理间隔(秒)
'cleanup_interval' => (int) env('JWT_CLEANUP_INTERVAL', 3600),
],
// 中间件配置
'middleware' => [
// 排除的路由路径(正则),这些路径不校验 JWT
'except' => [],
],
];
| 驱动 | 适用场景 |
|------|----------|
| file | 单机部署、低并发 |
| redis | 分布式部署、高性能 |
| database | 需要持久化、跨数据中心 |
| memcached | 高吞吐量、自动过期 |
firebase/php-jwt 的 $leeway 是全局静态属性。同一进程中若存在多个不同 leeway 配置的 JWT 实例,后面的调用会覆盖前面的值。如需在同一应用中使用不同 leeway,请确保所有 JWT 实例使用相同的 leeway 配置。
auto_cleanup 使用 register_shutdown_function 实现,在传统 PHP-FPM 模式下工作正常。但在 webman(Workerman)和 Hyperf(Swoole/Swow)等常驻内存进程中,shutdown 函数仅在 worker 进程退出时触发,不会在每个请求后执行。
在常驻进程模式下,建议通过框架自身的定时器机制定期调用清理:
Webman(Cron 定时任务):
// config/plugin/webman/cron/app.php
\Erikwang2013\Jwt\JWT::class => [
'handler' => function ($jwt) { $jwt->cleanup(); },
'rule' => '0 */1 * * *', // 每小时执行一次
],
Hyperf(Crontab 注解):
use Hyperf\Crontab\Annotation\Crontab;
#[Crontab(name: 'JwtCleanup', rule: '0 */1 * * *')]
public function cleanup(): void { $this->jwt->cleanup(); }
| 微信 WeChat | 支付宝 Alipay |
|:---:|:---:|
|
|
|
MIT