agielks / yii2-jwt
基于 Icobucci 版本 4.1 的 JWT
1.0.0
2022-07-13 05:18 UTC
Requires
- php: >=8.0
- lcobucci/jwt: ~4.1.0
- yiisoft/yii2: ~2.0.0
Requires (Dev)
- phpunit/phpunit: ~9.5.0
This package is auto-updated.
Last update: 2024-09-19 10:58:36 UTC
README
此扩展为 Yii 框架 2.0(需要 PHP 8.0+)提供了 JWT 集成(基于 https://github.com/lcobucci/jwt)。它包含基本的 HTTP 身份验证支持。
目录
安装
此包可在 Packagist 上找到,您可以使用 Composer 安装它。
composer require agielks/yii2-jwt ~1.0
或将它添加到您的 composer.json
文件的 require 部分。
"agielks/yii2-jwt": "~1.0"
依赖
- PHP 8.0+
- OpenSSL 扩展
- Sodium 扩展
- lcobucci/jwt 4.1
基本用法
将 jwt
组件添加到您的配置文件中,
'components' => [ 'jwt' => [ 'class' => \agielks\yii2\jwt\Jwt::class, // 'singer' => new \Lcobucci\JWT\Signer\Hmac\Sha256(), 'signer' => 'HS256', // 'key' => \Lcobucci\JWT\Signer\Key\InMemory::plainText('my-key'), 'key' => 'my-key', , ], ],
重要:如果您不提供签名者和密钥,它将使用不安全的签名者
按照以下方式配置 authenticator
行为。
namespace app\controllers; class SiteController extends \yii\rest\Controller { /** * @inheritdoc */ public function behaviors() { $behaviors = parent::behaviors(); $behaviors['authenticator'] = [ 'class' => \agielks\yii2\jwt\JwtBearerAuth::class, ]; return $behaviors; } }
您还可以使用 CompositeAuth
,参考 文档。
创建令牌
/* @var $jwt \agielks\yii2\jwt\Jwt */ $now = new DateTimeImmutable(); $jwt = Yii::$app->get('jwt'); $token = $jwt ->builder() // Configures the issuer (iss claim) ->issuedBy('http://example.com') // Configures the audience (aud claim) ->permittedFor('http://example.org') // Configures the id (jti claim) ->identifiedBy('62cbfaca6bf7e') // Configures the time that the token was issue (iat claim) ->issuedAt($now) // Configures the time that the token can be used (nbf claim) required for StrictValidAt constraint ->canOnlyBeUsedAfter($now) // Configures the expiration time of the token (exp claim) ->expiresAt($now->modify('+1 hour')) // Configures a new claim, called "uid" ->withClaim('uid', '62cbfaca6bf7e') // Configures a new header, called "foo" ->withHeader('foo', 'bar') // Builds a new token ->getToken($jwt->signer(), $jwt->key()); // Retrieves all headers $token->headers()->all(); // Retrives typ from headers $token->headers()->get('typ'); // Print typ from headers print_r($token->headers()->get('typ')); // Retrieves all claims $token->claims()->all(); // Retrieves jti from claims $token->claims()->get('jti'); // Print jti from claims print_r($token->claims()->get('jti'));
从字符串解析令牌
/* @var $jwt \agielks\yii2\jwt\Jwt */ $now = new DateTimeImmutable(); $jwt = Yii::$app->get('jwt'); $token = $jwt ->builder() // ... ->expiresAt($now->modify('+1 hour')) ->getToken($jwt->signer(), $jwt->key()) ->toString(); // Parse without validation $data = $jwt->config()->parser()->parse($token); // Parse with validation $data = $jwt->load($token); // Print all headers print_r($data->headers()->all()); // Print all claims print_r($data->claims()->all()); // Validate token var_dump($data->isExpired($now)); var_dump($data->isExpired($now->modify('+2 hour')));
验证令牌
您可以在组件中进行简单的配置来自定义验证
use \agielks\yii2\jwt\Jwt; use \Lcobucci\JWT\Signer\Hmac\Sha256; use \Lcobucci\JWT\Signer\Key\InMemory; use \Lcobucci\JWT\Validation\Constraint\LooseValidAt; use \Lcobucci\JWT\Validation\Constraint\SignedWith; use \Lcobucci\JWT\Validation\Constraint\IdentifiedBy; use \Lcobucci\Clock\SystemClock; 'components' => [ 'jwt' => [ 'class' => Jwt::class, 'signer' => new Sha256(), 'key' => InMemory::plainText('my-key'), 'constraints' => [ new LooseValidAt(SystemClock::fromSystemTimezone()), new SignedWith( new Sha256(), InMemory::plainText('my-key') ), new IdentifiedBy('my-identity'), ], ], ],
登录示例
基本方案
- 客户端发送凭证。例如,登录 + 密码
- 应用程序验证凭证
- 如果凭证有效,客户端将收到令牌
- 客户端将令牌存储以供未来请求使用
逐步使用方法
- 安装组件
composer require agielks/yii2-jwt ~1.0
- 更新您的组件配置
'components' => [ // other components here... 'jwt' => [ 'class' => \agielks\yii2\jwt\Jwt::class, // 'singer' => new \Lcobucci\JWT\Signer\Hmac\Sha256(), 'signer' => 'HS256', // 'key' => \Lcobucci\JWT\Signer\Key\InMemory::plainText('my-key'), 'key' => 'my-key', , ], // ... ],
- 更改方法
User::findIdentityByAccessToken()
/** * {@inheritdoc} * @param \Lcobucci\JWT\Token $token */ public static function findIdentityByAccessToken($token, $type = null) { return static::findOne(['id' => $token->claims()->get('uid')]); }
如果您想使用 auth_key 作为密钥,请更新方法如下
/** * {@inheritdoc} * @param \Lcobucci\JWT\Token $token */ public static function findIdentityByAccessToken($token, $type = null) { return static::findOne(['auth_key' => $token->claims()->get('auth_key')]); }
- 创建控制器
use agielks\yii2\jwt\JwtBearerAuth; // Use your own login form use common\models\LoginForm; use DateTimeImmutable; use Yii; use yii\base\InvalidConfigException; use yii\filters\Cors; use yii\rest\Controller; use yii\web\Response; /** * Class SiteController */ class SiteController extends Controller { /** * {@inheritdoc} */ public function behaviors() { $behaviors = parent::behaviors(); $behaviors['contentNegotiator']['formats']['text/html'] = Response::FORMAT_JSON; $behaviors['corsFilter'] = ['class' => Cors::class]; $behaviors['authenticator'] = [ 'class' => JwtBearerAuth::class, 'optional' => [ 'login', ], ]; return $behaviors; } /** * {@inheritdoc} */ protected function verbs() { return [ 'login' => ['OPTIONS', 'POST'], ]; } /** * @return array|LoginForm * @throws InvalidConfigException */ public function actionLogin() { $model = new LoginForm(); if ($model->load(Yii::$app->getRequest()->getBodyParams(), '') && $model->login()) { /* @var $jwt \agielks\yii2\jwt\Jwt */ $now = new DateTimeImmutable(); $jwt = Yii::$app->get('jwt'); $user = $model->getUser(); return $jwt ->builder() // Configures the issuer (iss claim) ->issuedBy('http://example.com') // Configures the audience (aud claim) ->permittedFor('http://example.org') // Configures the id (jti claim) ->identifiedBy($user->id) // Configures the time that the token was issue (iat claim) ->issuedAt($now) // Configures the time that the token can be used (nbf claim) ->canOnlyBeUsedAfter($now) // Configures the expiration time of the token (exp claim) ->expiresAt($now->modify('+1 hour')) // Configures a new claim, called "uid" ->withClaim('uid', $user->id) // Configures a new claim, called "auth_key" ->withClaim('auth_key', $user->auth_key) // Returns a signed token to be used ->getToken($jwt->signer(), $jwt->key()) // Convert token to string ->toString(); } $model->validate(); return $model; } /** * Test authentication */ public function actionTest() { return ['auth' => 'success']; } }