stechstudio/laravel-jwt

辅助包,简化在Laravel中使用JWT令牌生成、消费和保护路由

2.3 2024-03-12 23:18 UTC

This package is auto-updated.

Last update: 2024-08-30 12:00:48 UTC


README

Laravel JWT工具

Latest Version on Packagist Software License Build Status

本包封装了优秀的 lcobucci/jwt 库,并具有以下优点

  1. JWT 门面和辅助方法,可快速生成和解析令牌。
  2. 对生成的令牌强制执行最小声明集,如 audissexp
  3. 验证解析的令牌以确保所需的声明已正确设置,且签名存在且有效。
  4. HTTP 中间件用于验证特定路由的JWT
  5. 请求宏,可轻松访问特定路由的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 提供的任何方法,以及一些新的方法,如 signWithlifetime

$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无法解析,将抛出异常。

验证收到的令牌

正如此包对生成的令牌应包含的内容有一些看法,我们希望确保这些最小要求在收到的任何令牌上都得到适当设置。

在解析收到的令牌后,只需调用 isValidvalidate 即可,具体取决于您是想得到布尔结果还是抛出异常。请确保传递预期的令牌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

此时,您可以确信令牌

  1. 已签名,并且签名已验证(使用配置的签名密钥)
  2. 在允许的时间内(尚未过期)
  3. 适用于您的应用程序(aud声明与配置的受众匹配)
  4. 具有预期的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

  1. 作为名为jwttoken的请求参数
  2. 作为名为jwttoken的路由参数
  3. 在授权头中,作为Token JWTBearer :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文件中。