stechstudio / laravel-jwt
辅助包,简化在Laravel中使用JWT令牌生成、消费和保护路由
Requires
- php: ^8.1
- illuminate/support: ^8.0|^9.0|^10.0|^11.0
- lcobucci/jwt: ^4.3
Requires (Dev)
- orchestra/testbench: ^7.0
- phpunit/phpunit: ~9.0
README
Laravel JWT工具
本包封装了优秀的 lcobucci/jwt 库,并具有以下优点
JWT
门面和辅助方法,可快速生成和解析令牌。- 对生成的令牌强制执行最小声明集,如
aud
、iss
和exp
。 - 验证解析的令牌以确保所需的声明已正确设置,且签名存在且有效。
- HTTP 中间件用于验证特定路由的JWT
- 请求宏,可轻松访问特定路由的JWT声明
快速入门
安装
composer require stechstudio/laravel-jwt
简单示例
您可以使用 get
方法生成简单的JWT。
$jwt = JWT::get('token-id', ['myclaim' => 'somevalue']);
这将生成一个包含提供的ID和声明数组的令牌,并返回字符串令牌。
有效期
默认令牌过期时间为10分钟,您可以进行配置,或您可以在创建令牌时指定一个自定义的有效期值作为第三个参数
$jwt = JWT::get('token-id', ['anything' => 'here'], 3600);
此令牌将在一小时后过期。您还可以使用Carbon指定有效期
$jwt = JWT::get('token-id', ['anything' => 'here'], now()->addMinutes(60));
签名密钥
如果您正在生成将被不同应用程序(我们公司中非常常见的用例)消费的JWT,您可以指定签名密钥作为第四个参数。
$jwt = JWT::get('token-id', ['anything' => 'here'], 3600, config('services.otherapp.key'));
配置
此包尝试选择合理的默认值,同时允许您通过.env文件更改配置。
签名密钥
每个令牌都会进行签名。如果可用,将使用 JWT_SIGNING_KEY
值,否则将使用 APP_KEY
作为签名密钥。
有效期
默认有效期是600秒/10分钟。您可以通过指定秒数作为 JWT_LIFETIME
来更改默认值。
发行者
默认令牌发行者(iss
声明)是您的 APP_NAME
小写。您可以通过 JWT_ISSUER
指定不同的发行者名称。
受众
默认令牌受众(aud
声明)是您的 APP_NAME
小写。您可以通过 JWT_AUDIENCE
指定不同的受众名称。
流畅地构建令牌
到目前为止,我们已经看到了 JWT::get()
辅助方法,它在简单需求中非常快速。
为了对您的令牌有更多控制,您可以创建它而不是生成。
您可以使用 基础 Builder
类 提供的任何方法,以及一些新的方法,如 signWith
和 lifetime
。
$token = JWT::identifiedBy('my-token-id') ->lifetime(3600) ->signWith('custom-signing-key-with-256-bits') ->issuedBy("my-app") ->permittedFor("receiving-app") ->withClaim('myclaim', 'any value') ->getToken() ->toString();
解析
您可以解析JWT字符串到令牌
$token = JWT::parse("... JWT string ...");
如果JWT无法解析,将抛出异常。
验证收到的令牌
正如此包对生成的令牌应包含的内容有一些看法,我们希望确保这些最小要求在收到的任何令牌上都得到适当设置。
在解析收到的令牌后,只需调用 isValid
或 validate
即可,具体取决于您是想得到布尔结果还是抛出异常。请确保传递预期的令牌ID。
$token = JWT::parse("... JWT string ..."); $token->isValid('expected-token-id'); // Returns true or false $token->validate('expected-token-id'); // Throws exceptions for any validation failure
此时,您可以确信令牌
- 已签名,并且签名已验证(使用配置的签名密钥)
- 在允许的时间内(尚未过期)
- 适用于您的应用程序(
aud
声明与配置的受众匹配) - 具有预期的ID
验证异常
当调用validate('expected-token-id')
时,根据验证失败将抛出以下异常
STS\JWT\Exceptions\InvalidSignature
STS\JWT\Exceptions\TokenExpired
STS\JWT\Exceptions\InvalidAudience
STS\JWT\Exceptions\InvalidID
STS\JWT\Exceptions\ValidationException
将用于其他类型的验证失败。
检索声明
一旦您已解析和验证了令牌,您可以使用getClaims
或简单地使用toArray
检索所有令牌声明。
如果您只想检索自定义有效负载声明,请使用getPayload
;
// Make our string token $jwt = JWT::get('token-id', ['foo' => 'bar']); // Parse it and validate $token = JWT::parse($jwt)->validate('token-id'); // Ignore registered claims, just get our custom claims $token->getPayload(); // [ foo => bar ]
或要检索单个声明,请使用get
并传入声明名称。您可以选择作为第二个参数传入默认值;
$token->get("foo"); // bar $token->get("invalid"); // null $token->get("invalid", "quz"); // quz
路由中间件
我们经常使用JWT来授权请求。有时这些JWT由同一应用程序生成和消费,但更常见的是用于跨应用程序授权。
您可以使用包含的jwt
中间件来验证JWT请求。中间件将在多个位置查找JWT
- 作为名为
jwt
或token
的请求参数 - 作为名为
jwt
或token
的路由参数 - 在授权头中,作为
Token JWT
或Bearer :base64encodedJWT
如果在这些位置中的任何一个找到了令牌,它将被解析和验证。
令牌ID
默认情况下,预期令牌ID将与路由名称匹配。
例如,使用以下路由,令牌需要一个ID为my.home
Route::get('/home', [Controller::class, 'home'])->name('my.home')->middleware('jwt');
您可以通过传递为中间件参数来指定所需的ID
Route::get('/home', [Controller::class, 'home'])->middleware('jwt:expected-id');
请求上的访问声明
所有令牌声明
Laravel Request
上有一个getClaim
宏,因此您可以从任何地方获取声明。
示例:当将$request
注入控制器方法时
use Illuminate\Http\Request; class Controller { public function home(Request $request) { echo $request->getClaim('aud'); // The token audience } }
自定义有效负载合并
令牌有效负载(添加到JWT的自定义声明,不属于核心注册声明集)合并到请求属性中,因此您可以像访问其他请求属性一样访问它们。
如果JWT有一个foo
声明,您可以直接访问$request->foo
或$request->input('foo')
或甚至使用全局请求助手request('foo')
。
注意:当有效负载合并到请求时,我们可能会覆盖一些现有的请求属性。因为我们非常信任验证的JWT中的有效负载,所以我们更喜欢这种行为。但是,如果您想禁用,请将JWT_MERGE_PAYLOAD=false
设置在您的.env文件中。