astrotechlabs / yii2-jwt-tools
在 Yii Framework 2 项目上配置 JWT 身份验证和验证的简单方法
Requires
- php: >=8
- firebase/php-jwt: ^5.2
- yiisoft/yii2: ^2.0
Requires (Dev)
This package is auto-updated.
Last update: 2024-09-24 16:48:46 UTC
README
JWT Tools 是一个工具箱,可以帮助您配置使用 JWT 令牌进行身份验证。不仅限于身份验证,还包括签名验证和著名的密钥。
我最大的动力是,因为我没有看到一种简单的方式来设置简单的 JWT 验证和一些辅助函数。我总是需要将整个代码复制粘贴到一个新项目中。
按照以下步骤安装和设置到您的项目中。
安装
安装此扩展的首选方式是通过 composer。
要安装,请运行以下命令之一:
$ php composer.phar require dersonsena/yii2-jwt-tools
或
"dersonsena/yii2-jwt-tools": "^1.0"
将其添加到您的 composer.json
文件的 require
部分。
使用方法
配置文件
让我们确保一些应用程序设置是正确的。打开您的 config/web.php
并进行如下设置:
'components' => [ // ... 'request' => [ 'enableCookieValidation' => false, ], 'user' => [ 'identityClass' => 'app\models\User', 'enableAutoLogin' => false, 'enableSession' => false, 'loginUrl' => null ], // ...
控制器
在您的控制器类中,在 behaviors()
方法中注册 JWTSignatureBehavior 和 HttpBearerAuth 行为,如下所示
use yii\rest\Controller; class YourCuteController extends Controller { public function behaviors() { $behaviors = parent::behaviors(); $behaviors['jwtValidator'] = [ 'class' => JWTSignatureBehavior::class, 'secretKey' => Yii::$app->params['jwt']['secret'], 'except' => ['login'] // it's doesn't run in login action ]; $behaviors['authenticator'] = [ 'class' => HttpBearerAuth::class, 'except' => ['login'] // it's doesn't run in login action ]; return $behaviors; } }
注意:在这个例子中,我使用了
Yii::$app->params['jwt']['secret']
来存储我的 JWT 密钥,但我也非常喜欢 .env 文件,这些信息可以存储在那里。
JWTSignatureBehavior
将验证通过 Authorization
HTTP 标头发送的 JWT 令牌。如果令牌存在问题,它将抛出以下异常之一
-
UnauthorizedHttpException,消息为
您的请求未包含身份验证令牌。
如果 HTTP 标头不存在或令牌为空或为空值。 -
UnauthorizedHttpException,消息为
身份验证令牌已过期。
如果令牌已过期。 -
UnauthorizedHttpException,消息为
令牌签名无效。
如果令牌签名无效。
如果出于某种原因您需要更改 HTTP 标头的名称(说实话,我看不到这种情况)
class YourCuteController extends Controller { // ... public function behaviors() { $behaviors['jwtValidator'] = [ 'class' => JWTSignatureBehavior::class, 'secretKey' => Yii::$app->params['jwt']['secret'], 'headerName' => 'Auth' ]; } // ... }
在您的登录操作中,您需要创建一个 JWT 令牌来发送响应。创建令牌非常简单,如下所示
class YourCuteController extends Controller { // ... public function behaviors() { $behaviors['jwtValidator'] = [ 'class' => JWTSignatureBehavior::class, 'secretKey' => Yii::$app->params['jwt']['secret'], 'headerName' => 'Auth' ]; } public function actionLogin() { // validation stuff // find user $token = JWTTools::build(Yii::$app->params['jwt']['secret']) ->withModel($user, ['name', 'email', 'group']) ->getJWT(); return ['success' => true, 'token' => $token]; } // ... }
模型身份类
到此为止,我们知道令牌是有效的,我们可以对其进行解码以进行用户认证。
我在这里使用 app/models/User
作为我的用户身份,因此让我们实现 IdentityInterface 接口的 findIdentityByAccessToken()
方法
namespace app\models; use yii\db\ActiveRecord; use yii\web\IdentityInterface; class User extends ActiveRecord implements IdentityInterface { // ... public static function findIdentity($id) { return static::findOne($id); } public function getId() { return $this->id; } public function getAuthKey() { // we don't need to implement this method } public function validateAuthKey($authKey) { // we don't need to implement this method } public static function findIdentityByAccessToken($token, $type = null) { $decodedToken = JWTTools::build(Yii::$app->params['jwt']['secret']) ->decodeToken($token); return static::findOne(['id' => $decodedToken->sub]); } }
如果一切顺利,此时您可以使用有效的 JWT 令牌进行身份验证。
演示
生成令牌
您可以使用 JWTTools 方法在项目中执行特定操作。以下是一些示例
use AstrotechLabs\JWTTools\JWTTools; $jwtTools = JWTTools::build('my-secret-key'); $token = $jwtTools->getJWT(); $payload = $jwtTools->getPayload()->getData(); var_dump($token); print_r($payload);
此代码将返回类似的内容
string(248) "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6ImJlMTgzOTQ4YjJmNjkzZSJ9.eyJzdWIiOiJiZTE4Mzk0OGIyZjY5M2UiLCJpc3MiOiIiLCJhdWQiOiIiLCJpYXQiOjE1ODkxMzEzNjIsImV4cCI6MTU4OTEzNDk2MiwianRpIjoiNTM4NTRiMGQ5MzFkMGVkIn0.-JDBkID1oJ7anC_JLg68AJxbKGK-5ubA83zZlDZYYso"
Array
(
[sub] => 9c65241853de774
[iss] =>
[aud] =>
[iat] => 1589129672
[exp] => 1589133272
[jti] => a0a98e2364d2721
)
注意:
->getPayload()
返回一个 JWTPayload 实例。
使用 Active Record 生成 Token
您可以使用 withModel()
方法将 Active Record 属性插入到负载中,如下所示
use AstrotechLabs\JWTTools\JWTTools; $user = app\models\User::findOne(2); $payload = JWTTools::build('my-secret-key'); ->withModel($user, ['id', 'name', 'email']) ->getPayload() ->getData(); print_r($payload);
此代码将返回类似的内容
Array
(
[sub] => 10 <~~~~
[iss] =>
[aud] =>
[iat] => 1589130028
[exp] => 1589133628
[jti] => 7aba5b7666d7868
[id] => 10 <~~~~
[name] => Kilderson Sena <~~~~
[email] => email@email.com.br <~~~~
)
sub
属性会自动覆盖为 $model->getPrimaryKey()
的值,遵循 RFC7519 指令。
更改 JWT 属性
您可以通过在第二个方法参数中添加一个数组来更改 JWT 属性(如 iss
,aud
等),如下所示
use AstrotechLabs\JWTTools\JWTTools; $payload = JWTTools::build('my-secret-key', [ 'algorithm' => 'ES256', 'expiration' => 1589069866, //<~~ It will generate the exp property automatically 'iss' => 'yourdomain.com', 'aud' => 'yourdomain.com', ]);
作者
- Kilderson Sena - 初始工作 - Yii Academy
还可以查看参与此项目的贡献者列表。
贡献
欢迎 Pull requests。对于重大更改,请先打开一个 issue 以讨论您想要更改的内容。
请确保适当更新测试。