raphaelbsr/yii2-jwt-tools

在 Yii Framework 2 项目中配置 JWT 认证和验证的简单方法

安装次数: 0

依赖者: 0

建议者: 0

安全: 0

星标: 0

关注者: 1

分支: 9

类型:yii2-extension

1.0.4 2020-06-29 23:09 UTC

This package is auto-updated.

Last update: 2024-09-29 05:49:50 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 Dersonsena\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 Dersonsena\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 <~~~~
)

根据 RFC7519 指示,sub 属性会自动重写为 $model->getPrimaryKey() 的值。

更改 JWT 属性

您可以通过在第二个方法参数中添加一个数组来更改 JWT 属性(例如 issaud 等),如下所示

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

作者

请参阅参与此项目的 贡献者列表

贡献

欢迎提交拉取请求。对于重大更改,请先打开一个问题以讨论您想更改的内容。

请确保根据需要更新测试。

许可证

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