kozlovsv/yii2-jwt-auth

为 Yii2 的 JWT 认证扩展

安装: 31

依赖者: 1

建议者: 0

安全: 0

星星: 1

关注者: 1

分支: 0

开放问题: 0

类型:yii2-extension

dev-master 2023-05-05 14:49 UTC

This package is auto-updated.

Last update: 2024-09-05 17:32:20 UTC


README

该库实现了通过 JWT 令牌进行授权。

在授权过程中,使用两个令牌:刷新令牌和访问令牌。访问令牌短生命周期可重复使用,刷新令牌是长期的单次使用。

应用缓存组件(Yii::$app->cache)用于存储令牌,令牌不会保存到数据库。只存储令牌 ID,一个唯一的 MD5 缓存。因此它是安全的。刷新令牌存储用于重新发放访问令牌。

访问令牌的存储用作令牌白名单,如果存储的令牌不在列表中,则授权不会通过,即使令牌有有效的签名和过期日期

安装

安装此扩展的首选方式是通过 composer

运行以下命令之一:

php composer.phar require --prefer-dist kozlovsv/yii2-jwt-auth "@dev"

或者

"kozlovsv/yii2-jwt-auth": "@dev"

将以下内容添加到您的 composer.json 文件的 require 部分。

依赖

基本用法

jwt 组件添加到您的配置文件中,

'components' => [
    'jwt' => [
        'class' => \kozlovsv\jwtauth\Jwt::class,
        'accessTokenSecret' => 'Your access token secret',
        'refreshTokenSecret' => 'Your refresh token secret', //Not equal to access secret
        'alg' => 'HS256', //signing algorithm to use
        'durationAccess' => 1800, //default 30 min
        'durationRefresh' => 1296000, //default 15 days
        'leeway' => 0, //clock skew
    ],
],

按照以下方式配置 authenticator 行为。

namespace app\controllers;

class ExampleController extends \yii\rest\Controller
{

    /**
     * @inheritdoc
     */
    public function behaviors()
    {
        $behaviors = parent::behaviors();
        $behaviors['authenticator'] = [
            'class' => \kozlovsv\jwtauth\JwtHttpBearerAuth::class,
        ];

        return $behaviors;
    }
}

您还可以与 CompositeAuth 一起使用,请参阅 文档

Yii2 基本模板示例

基本方案

认证方案基于此 规范

  1. 客户端发送凭证。例如,登录 + 密码。在我们的例子中,这是一个发送到 https://your-domain/rest/login 的 POST 请求。
  2. 后端验证它们
  3. 如果凭证有效,客户端将收到一对令牌:刷新和访问
  4. 客户端将令牌存储在未来的请求中
  5. 客户端使用访问令牌向后端发送请求进行认证。在我们的例子中,这是一个发送到 https://your-domain/rest/data 的请求。在请求头的部分中,必须指定头 Authorization: Bearer YOUR_ACCESS_TOKEN
  6. 如果访问令牌已过期,后端将发送带有 401 HTTP 状态的响应
  7. 客户端发送带有刷新令牌的查询,以更新一对令牌。在我们的例子中,这是一个发送到 https://your-domain/rest/refresh-token 的 POST 请求。刷新令牌的 POST 参数名为 refresh_token='Your refresh token'
  8. 如果刷新令牌无效,则转到步骤 1

逐步使用示例

  1. 安装组件

    php composer.phar require --prefer-dist kozlovsv/yii2-jwt-auth "@dev"
  2. 将以下内容添加到 config/web.php 的 components 部分

    $config = [
        'components' => [
            // other default components here..
            'jwt' => [
                'class' => \kozlovsv\jwtauth\Jwt::class,
                'accessTokenSecret' => 'Your access token secret',
                'refreshTokenSecret' => 'Your refresh token secret', //Not equal to access secret
                'alg' => 'HS256', //signing algorithm to use
                'durationAccess' => 1800, //default 30 min
                'durationRefresh' => 1296000, //default 15 days
                'leeway' => 0, //clock skew
            ],
        ],
    ];
  3. 更改方法 app\models\User::findIdentityByAccessToken()

    /**
     * @param int $token User id
     * @inheritdoc
     */
    public static function findIdentityByAccessToken($token, $type = null)
    {
        $user = self::findOne((int) $token);
        if ($user) return $user;
        return null;
    }
  4. 创建控制器

    <?php
    
    namespace app\controllers;
    
    use kozlovsv\jwtauth\Jwt;
    use kozlovsv\jwtauth\RefreshTokenPairBodyAction;
    use Yii;
    use yii\web\UnauthorizedHttpException;
    
    class RestController extends Controller
    {
        /**
         * @inheritdoc
         */
        public function behaviors()
        {
            $behaviors = parent::behaviors();
            $behaviors['authenticator'] = [
                'class' => \kozlovsv\jwtauth\JwtHttpBearerAuth::class,
                'optional' => [
                    'rest/login',
                    'rest/refresh-token'
                ],
            ];
            return $behaviors;
        }
    
        public function actions()
        {
            //Add to refresh token pair action
            return [
                'refresh-token' => RefreshTokenPairBodyAction::class,
            ];
        }
    
        /**
          * @return \yii\web\Response
          * @throws UnauthorizedHttpException
          * @throws \yii\base\InvalidConfigException
          */
        public function actionLogin() {
            $model = new \app\models\form\LoginForm([
                'rememberMe' => false,
            ]);
            if ($model->load(Yii::$app->request->getBodyParams(), '') && $model->login()) {
                $user = Yii::$app->user->identity;
    
                /** @var Jwt $jwtServ */
                $jwtServ = Yii::$app->get('jwt');
                list($refreshToken, $acsessToken) = $jwtServ->generateAndSavePairTokens($user->getId());
                return $this->asJson([
                    'user_id' => $user->getId(),
                    'access_token' =>  $acsessToken,
                    'refresh_token' =>  $refreshToken,
                   ]);
            }
            throw new UnauthorizedHttpException('Your request was made with invalid credentials. ' . implode(',', $model->getFirstErrors()));
        }
    
        /**
         * @return \yii\web\Response
         */
        public function actionData()
        {
            return $this->asJson([
                'success' => true,
            ]);
        }
    }