基于 tymon/jwt-auth 适配 Hyperf 框架的 JSON Web Token 认证包。
- 完整的 JWT 编码/解码/刷新/黑名单机制
- 协程安全(使用 Hyperf Context 存储请求级状态)
- PSR-15 中间件
- 支持 HMAC / RSA / ECDSA 算法
- 基于 Lcobucci JWT 库
- 可插拔的 Provider 架构(JWT / Auth / Storage)
- Hyperf ConfigProvider 自动注册
- 命令行生成密钥
composer require kooditorm/hyperf-jwt发布配置文件:
php bin/hyperf.php vendor:publish kooditorm/hyperf-jwt生成密钥:
php bin/hyperf.php jwt:secret配置文件位于 config/autoload/jwt.php:
return [
'secret' => env('JWT_SECRET'),
'ttl' => 60, // token 有效期(分钟)
'refresh_ttl' => 20160, // 刷新窗口(分钟)
'algo' => 'HS256', // 签名算法
'blacklist_enabled' => true, // 启用黑名单
'user_model' => 'App\Model\User',
// ...
];namespace App\Model;
use Kooditorm\Hyperf\Jwt\Contracts\JWTSubject;
use Hyperf\Database\Model\Model;
class User extends Model implements JWTSubject
{
public function getJWTIdentifier(): mixed
{
return $this->getKey();
}
public function getJWTCustomClaims(): array
{
return [
// 'role' => 'admin',
];
}
public function getAuthPassword(): string
{
return $this->password;
}
}use Kooditorm\Hyperf\Jwt\JWTAuth;
class AuthController
{
public function __construct(private JWTAuth $jwt) {}
public function login()
{
$credentials = [
'email' => $request->input('email'),
'password' => $request->input('password'),
];
if (! $token = $this->jwt->attempt($credentials)) {
return ['error' => 'Unauthorized'];
}
return [
'token' => $token,
'token_type' => 'bearer',
'expires_in' => $this->jwt->factory()->getTTL() * 60,
];
}
// 从指定用户生成 token
public function tokenForUser(User $user): string
{
return $this->jwt->fromUser($user);
}
}在 config/autoload/middlewares.php 中注册:
return [
'http' => [
// 路由级中间件
],
];或直接在控制器注解中使用:
use Kooditorm\Hyperf\Jwt\Http\Middleware\JWTAuthMiddleware;
class UserController
{
#[Middleware(JWTAuthMiddleware::class)]
public function profile()
{
$user = $this->jwt->user();
return $user;
}
}// 刷新当前 token
$newToken = $this->jwt->parseToken()->refresh();
// 或使用中间件自动刷新
use Kooditorm\Hyperf\Jwt\Http\Middleware\JWTRefreshMiddleware;
#[Middleware(JWTRefreshMiddleware::class)]
public function refresh()
{
// 新 token 已在 Authorization 响应头中
}$this->jwt->parseToken()->invalidate(); // 拉黑当前 token
$this->jwt->parseToken()->invalidate(true); // 永久拉黑use Kooditorm\Hyperf\Jwt\Facades\JWTAuth;
$token = JWTAuth::attempt($credentials);
$user = JWTAuth::user();
$payload = JWTAuth::payload();| 中间件 | 说明 |
|---|---|
JWTAuthMiddleware |
验证 token 并认证用户,失败返回 401 |
JWTCheckMiddleware |
检查 token 有效性,不强制要求 |
JWTRefreshMiddleware |
刷新 token,新 token 放入响应头 |
JWTAuthAndRenewMiddleware |
认证 + 刷新 token |
use Kooditorm\Hyperf\Jwt\Contracts\Providers\Auth;
class MyAuthProvider implements Auth
{
public function byCredentials(array $credentials): bool { ... }
public function byId(mixed $id): bool { ... }
public function user(): mixed { ... }
}在 ConfigProvider 中绑定:
// config/autoload/dependencies.php
return [
\Kooditorm\Hyperf\Jwt\Contracts\Providers\Auth::class => \App\Provider\MyAuthProvider::class,
];use Kooditorm\Hyperf\Jwt\Contracts\Providers\Storage;
use Hyperf\Redis\Redis;
class RedisStorage implements Storage
{
public function __construct(private Redis $redis) {}
public function add(string $key, mixed $value, int $minutes): void
{
$this->redis->setex($key, $minutes * 60, serialize($value));
}
public function forever(string $key, mixed $value): void
{
$this->redis->set($key, serialize($value));
}
public function get(string $key): mixed
{
$val = $this->redis->get($key);
return $val !== false ? unserialize($val) : null;
}
public function destroy(string $key): bool
{
return (bool) $this->redis->del($key);
}
public function flush(): void
{
$this->redis->flushDB();
}
}本包使用 Hyperf\Context\Context 存储当前请求的 token 和认证用户,确保在 Swoole 协程环境下安全使用。每个协程拥有独立的 token 上下文,互不干扰。
- tymon/jwt-auth - 原始 JWT 包
- lcobucci/jwt - JWT 编解码库
- Hyperf - 高性能协程框架
MIT