astrotechlabs/yii2-jwt-tools

在 Yii Framework 2 项目上配置 JWT 身份验证和验证的简单方法

安装次数: 2,094

依赖项: 1

建议者: 0

安全: 0

星星: 30

关注者: 4

分支: 9

公开问题: 2

类型:yii2-extension

1.0.7 2023-04-18 01:14 UTC

This package is auto-updated.

Last update: 2024-09-24 16:48:46 UTC


README

GitHub GitHub repo size Packagist Stars Packagist PHP Version Support (specify version) Packagist Downloads

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() 方法中注册 JWTSignatureBehaviorHttpBearerAuth 行为,如下所示

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 令牌。如果令牌存在问题,它将抛出以下异常之一

如果出于某种原因您需要更改 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 属性(如 issaud 等),如下所示

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',
]);

作者

还可以查看参与此项目的贡献者列表

贡献

欢迎 Pull requests。对于重大更改,请先打开一个 issue 以讨论您想要更改的内容。

请确保适当更新测试。

许可证

此包在 MIT 许可证下发布。有关详细信息,请参阅附带LICENSE 文件。