rafalswierczek / jwt
简单的JWT代码库
3.0
2024-08-04 21:48 UTC
Requires
- php: 8.3.*
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.54
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^10.5
README
使用此仓库的帮助,完全控制JWS身份验证。
安装
composer require rafalswierczek/jwt
使用
请记住,这个库是一个代码库,所以将其视为您的源代码。注意合同中定义的异常,并捕获它们。
除非您对要实施的整个架构有100%的了解,否则什么都不会工作。
对称签名系统
- 非常安全地保管您的JWS密钥,并在应用程序之间共享,以便一个JWS可用于与多个应用程序进行身份验证。这几乎就是使用JWT系统的主要原因。
- 在认证服务器或单体中的认证模块
- 创建自己的端点,该端点将检查用户凭据,并在成功响应中返回生成的JWS。
- 创建自己的
JWSIssuerInterface、JWSHeader和JWSPayload实例,并生成应在认证端点返回的新JWS。 - 创建自己的
RefreshTokenProviderInterface实例,并生成应与JWS一起返回的新刷新令牌。 - 您**必须**为每个刷新令牌有1个唯一的密钥。将它们存储在具有唯一索引的表中。如果刷新令牌被破解或有人使用它应该被禁止,那么根据JWT系统的定义,您无法做任何事情。处理这种情况的唯一方法是使与刷新令牌关联的密钥在该表中无效,以防止用户生成新的JWS,该JWS应根据安全措施在3~15分钟内有效。
// Issuer example: namespace YourApp\AuthServer\Infrastructure; use YourApp\AuthServer\Application\JWSIssuer; use YourApp\AuthServer\Domain\Header; use YourApp\AuthServer\Domain\Payload; use YourApp\AuthServer\Domain\User; use rafalswierczek\JWT\JWS\Enum\Header\AlgorithmType; use rafalswierczek\JWT\JWS\Enum\Header\TokenType; use rafalswierczek\JWT\JWS\Issuer\JWSIssuerInterface; use rafalswierczek\JWT\JWS\Model\JWSHeader; use rafalswierczek\JWT\JWS\Model\JWSPayload; use rafalswierczek\Uuid4\Uuid4Factory; final class RafalswierczekJWSIssuer implements JWSIssuer { public function __construct(private JWSIssuerInterface $issuer) { } public function issueToken(User $user): string { $header = Header::create(); $payload = Payload::create( jwtId: Uuid4Factory::create()->toHex(), userId: $user->id, ); return $this->issuer->generateCompactJWS( header: $this->mapHeader($header), payload: $this->mapPayload($payload, $user), secret: $_ENV['JWS_PRIVATE_KEY'], ); } private function mapHeader(Header $header): JWSHeader { return new JWSHeader( tokenType: TokenType::from($header->typ), algorithmType: AlgorithmType::from($header->alg), ); } private function mapPayload(Payload $payload, User $user): JWSPayload { return new JWSPayload( id: $payload->jti, // globally unique JWT id issuer: $payload->iss, // domain of auth server (might be the same as audience element) subject: $payload->sub, // user-uuid issuedAt: (new \DateTimeImmutable())->setTimestamp($payload->iat), expirationTime: (new \DateTimeImmutable())->setTimestamp($payload->exp), audience: $payload->aud, // ['yourdomain1.com', 'yourdomain2.com'] data: ['user' => $user], // user metadata known to all audience applications ); } }
- 在匹配受众的每个应用程序中
- 创建自己的认证器,并从那里使用您的
JWSVerifierInterface实例验证请求头中的JWS。 - 如果JWS已过期(
JWSHasExpiredException),则尝试请求您的认证服务器使用当前刷新令牌生成新的JWS。返回403。 JWSCompromisedSignatureException是一个红旗,很可能是攻击或错误。将其记录为错误或警报,并返回403。CannotMatchAudienceException可能是旧域名的问题,或者JWS根本不应该用于该特定应用程序。将其记录为警告,并返回403。- 如果刷新令牌无效,请注销用户并强制他们使用您使用的任何凭据登录(认证服务器端点)。
- 创建自己的认证器,并从那里使用您的