brainpicker / reallysimplejwt
一个用于生成用户认证JSON Web Tokens的简单库。
Requires
- php: >=7.1.0
Requires (Dev)
- infection/infection: ^0.12.2
- phploc/phploc: ^4.0
- phpmd/phpmd: 2.6.*
- phpstan/phpstan: ^0.10
- phpunit/phpunit: ^7.0
- squizlabs/php_codesniffer: ^3.0
This package is not auto-updated.
Last update: 2024-09-27 12:57:56 UTC
README
一个简单的PHP库,用于创建使用HMAC SHA256进行签名签名的JSON Web Tokens。对于基本用法,库通过静态接口暴露,允许开发人员创建存储用户标识和过期时间的令牌。
库还支持扩展,开发人员可以定义自己的编码标准,设置所有RFC标准 JWT声明,并设置自己的私有声明。
注意:为PHP 5.6快速适配,未进行测试以验证
内容
什么是JSON Web Token?
JSON Web Tokens是一种创建关于用户或系统的声明的URL友好访问令牌的标准。
令牌分为三部分:头部、有效负载和签名;各部分之间用点分隔。每一部分都使用base64url标准进行编码,请参阅RFC。
一个JWT示例
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
头部和有效负载都是包含多个声明的编码JSON字符串
// Header { "alg": "HS256", "typ": "JWT" } // Payload { "sub": "1234567890", "name": "John Doe", "iat": 1516239022 }
声明是一个键值对,例如 "typ": "JWT"
,请阅读RFC 7519 了解更多关于JSON Web Token声明的信息。
通过签名实现令牌安全,签名由头部、有效负载和只有令牌作者知道的秘密组成。这些信息被散列,然后使用base64url进行编码。
如果恶意用户尝试编辑头部或有效负载声明,只要使用强密钥,他们将无法复制签名。有关更多信息,请参阅令牌安全。
设置
通过命令行Composer
composer require rbdwllr/reallysimplejwt
通过composer.json
"require": { "rbdwllr/reallysimplejwt": "^2.0" }
基本用法
对于基本用法,库通过ReallySimpleJWT\Token
类暴露一组静态方法,允许开发人员创建和验证基本的JSON Web Tokens。
创建令牌
调用create()
静态方法,并传递用户标识、密钥、过期日期时间数字和令牌发行者。
如果成功,将返回一个令牌字符串,如果失败,将抛出ReallySimpleJWT\Exception\ValidateException
异常。
use ReallySimpleJWT\Token; $userId = 12; $secret = 'sec!ReT423*&'; $expiration = time() + 3600; $issuer = 'localhost'; $token = Token::create($userId, $secret, $expiration, $issuer);
要创建更定制的令牌,开发人员可以使用customPayload()
方法。这允许根据表示有效负载声明的键值对数组创建令牌。
use ReallySimpleJWT\Token; $payload = [ 'iat' => time(), 'uid' => 1, 'exp' => time() + 10, 'iss' => 'localhost' ]; $secret = 'Hello&MikeFooBar123'; $token = Token::customPayload($payload, $secret);
如果成功,customPayload()
方法将返回一个JWT令牌字符串,如果失败,将抛出异常。
验证令牌
要验证JSON Web Token,请调用validate()
静态方法,并传递令牌字符串和密钥。验证方法检查令牌结构是否正确、签名是否有效、过期时间是否已过期以及不早于时间是否已过。
如果成功,它将返回true,如果失败,它将返回false。
use ReallySimpleJWT\Token; $token = 'aaa.bbb.ccc'; $secret = 'sec!ReT423*&' $result = Token::validate($token, $secret);
获取头和有效负载声明数据
要检索头或有效负载的令牌声明数据,请调用getHeader()
和/或getPayload()
静态方法。
这两个方法在成功时将返回关联数组,在失败时将抛出异常。
use ReallySimpleJWT\Token; $token = 'aaa.bbb.ccc'; $secret = 'sec!ReT423*&' // Return the header claims Token::getHeader($token, $secret); // Return the payload claims Token::getPayload($token, $secret);
工厂方法
ReallySimpleJWT\Token
类还提供了两个工厂方法,用于访问核心的 ReallySimpleJWT\Build
和 ReallySimpleJWT\Parse
类。
Token::builder(); // Returns an instance of ReallySimpleJWT\Build Token::parser($token, $secret); // Returns an instance of ReallySimpleJWT\Parse
高级用法
要创建自定义的 JSON Web Tokens,开发人员需要直接访问 ReallySimpleJWT\Build
和 ReallySimpleJWT\Parse
类。
创建自定义令牌
ReallySimpleJWT\Build
类允许您创建一个完全独特的 JSON Web Token。它提供了所有由 RFC 定义的头部和有效载荷声明的辅助方法。例如,setIssuer()
方法将添加 iss
声明到令牌有效载荷。
该类还允许开发人员通过 setHeaderClaim()
和 setPayloadClaim()
方法设置自定义的头部和有效载荷声明。
可以将这些方法链接在一起,当调用 build()
方法时,令牌将在 ReallySimpleJWT\Jwt
对象中生成并返回。
use ReallySimpleJWT\Build; use ReallySimpleJWT\Validate; use ReallySimpleJWT\Encode; $build = new Build('JWT', new Validate(), new Encode()); $token = $build->setContentType('JWT') ->setHeaderClaim('info', 'foo') ->setSecret('!secReT$123*') ->setIssuer('localhost') ->setSubject('admins') ->setAudience('https://google.com') ->setExpiration(time() + 30) ->setNotBefore(time() - 30) ->setIssuedAt(time()) ->setJwtId('123ABC') ->setPayloadClaim('uid', 12) ->build();
访问令牌
当开发人员在对 ReallySimpleJWT\Build
类调用 build()
方法时,将返回一个 ReallySimpleJWT\Jwt
对象。Jwt 类提供了两个方法 getToken()
和 getSecret()
。前者返回生成的 JSON Web Token,后者返回用于令牌签名的密钥。
要通过 ReallySimpleJWT\Parse
类解析 JSON Web Token,开发人员必须首先通过注入令牌和密钥创建一个新的 ReallySimpleJWT\Jwt
对象。
use ReallySimpleJWT\Jwt; $token = 'aaa.bbb.ccc'; $secret = '!secReT$123*'; $jwt = new Jwt($token, $secret); // Return the token $jwt->getToken(); // Return the secret $jwt->getSecret();
解析和验证令牌
ReallySimpleJWT\Parse
类允许开发人员解析和验证 JSON Web Token。有三个验证方法可用,它们都可以链接使用。
validate()
确认令牌的结构和签名的有效性。validateExpiration()
确认令牌过期声明(exp
)尚未过期。validateNotBefore()
确认令牌不早于声明(nbf
)已过。
如果提供的令牌有任何问题,每个验证方法都将抛出 ReallySimpleJWT\Exception\ValidateException
。
完成验证后应调用 parse()
方法,它将解码 JSON Web Token。然后,它将作为 ReallySimpleJWT\Parsed
对象返回结果。这将提供访问令牌在头部和有效载荷中持有的声明数据。
use ReallySimpleJWT\Parse; use ReallySimpleJWT\Jwt; use ReallySimpleJWT\Validate; use ReallySimpleJWT\Encode; $token = 'aaa.bbb.ccc'; $secret = '!secReT$123*'; $jwt = new Jwt($token, $secret); $parse = new Parse($jwt, new Validate(), new Encode()); $parsed = $parse->validate() ->validateExpiration() ->validateNotBefore() ->parse(); // Return the token header claims as an associative array. $parsed->getHeader(); // Return the token payload claims as an associative array. $parsed->getPayload();
访问令牌声明数据
当开发人员在对 ReallySimpleJWT\Parse
类调用 parse()
方法时,将返回 ReallySimpleJWT\Parsed
类。
它提供了许多辅助方法来获取令牌声明数据。开发人员可以调用 getHeader()
和 getPayload()
方法来获取相应的声明数据作为关联数组。
或者,开发人员可以调用一个符合 RFC 的声明方法之一
头部
getAlgorithm()
getType()
getContentType()
有效载荷
getIssuer()
getSubject()
getAudience()
getExpiration()
getNotBefore()
getIssuedAt()
getJwtId()
自定义编码
默认情况下,该库通过使用 sha256 算法通过 hash_hmac()
对 JWT 签名进行哈希和编码。如果开发人员想要使用自定义的编码形式,只需生成一个符合 ReallySimpleJWT\Interfaces\EncodeInterface
的自定义编码类。
interface EncodeInterface { public function getAlgorithm(): string; public function encode(string $toEncode): string; public function decode(string $toDecode): string; public function signature(string $header, string $payload, string $secret): string; }
错误消息和代码
在创建和解析 JWT 令牌的许多情况下,ReallySimpleJWT 库将抛出异常以突出显示问题。以下是错误代码、消息及其解释。
* 不再使用,库将不会生成此错误代码。
令牌安全
JWT(JSON Web Token)标准RFC 7519允许创建不带签名和带安全/哈希签名的令牌。然而,ReallySimpleJWT库默认强制执行安全性,因为没有任何逻辑理由不这样做。所有创建的令牌都必须有签名和一个强密码,但库将验证不带密码或强密码的令牌。该库将不验证不带签名的令牌。
可以通过创建一个实现了ReallySimpleJWT\Interfaces\EncodeInterface
的自定义编码类来编辑和增强签名及其安全性级别。请参阅自定义编码部分。
签名密钥
此JWT库强制实施严格的密码安全措施,如下所示:密码长度至少为12个字符;包含数字;大小写字母;以及以下特殊字符之一:*&!@%^#$
。
// Bad Secret secret123 // Good Secret sec!ReT423*&
这是因为有很多JWT破解工具,这意味着弱密码很容易被破解,从而使JWT提供的安全性变得无用。
第一版支持
本库的第一个版本支持将持续到2019年7月。该版本不会添加新功能,只会修复bug和安全补丁。
许可证
MIT
作者
Rob Waller
Twitter: @robdwaller