kozlovsv / yii2-jwt-auth
Extension for JWT auth for Yii2
Installs: 36
Dependents: 1
Suggesters: 0
Security: 0
Stars: 1
Watchers: 1
Forks: 0
Open Issues: 0
Type:yii2-extension
Requires
- php: >=7.2
- ext-json: *
- firebase/php-jwt: ~6.0
- yiisoft/yii2: ~2.0.14
This package is auto-updated.
Last update: 2025-02-05 18:16:43 UTC
README
The library implements authorization through the JWT token.
When authorizing, two tokens are used: a refresh token and an access token.Access token is short-lived reusable, refresh token is long-lived one-time.
The application cache component (Yii::$app->cache
) is used to store tokens, tokens are not saved to the database.
Only the token ID is stored, a unique MD5 cache. Therefore it is safe. Refresh token storage is used to reissue an access token.
Storage of access tokens is used as a whitelist of tokens, if the stored token is not in the list, authorization will not pass, even if the token has a valid signature and expiration date
Installation
The preferred way to install this extension is through composer.
Either run
php composer.phar require --prefer-dist kozlovsv/yii2-jwt-auth "@dev"
or add
"kozlovsv/yii2-jwt-auth": "@dev"
to the require section of your composer.json
file.
Dependencies
- PHP 7.2+
- firebase/php-jwt 6.0+
Basic usage
Add jwt
component to your configuration file,
'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 ], ],
Configure the authenticator
behavior as follows.
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; } }
Also you can use it with CompositeAuth
reffer to a doc.
Yii2 basic template example
Basic scheme
The authentication scheme is based on this specification.
- Client send credentials. For example, login + password. In our example, this is a POST request to https://your-domain/rest/login.
- Backend validate them
- If credentials is valid client receive pair token: refresh and access
- Client store tokens for the future requests
- Сlient sends a request to the backend using a access token for authentication. In our example, this is a request to https://your-domain/rest/data. In the header of the request section, you must specify the header
Authorization: Bearer YOUR_ACCESS_TOKEN
- If access token is expired, backent send response with 401 HTTP status
- Client send query with refresh token, for renew pair tokens. In our example, this is a POST request to https://your-domain/rest/refresh-token. Post parameter name for refresh token is
refresh_token='Your refresh token'
- If refresh token is invalid, go to step 1
Step-by-step usage example
-
Install component
php composer.phar require --prefer-dist kozlovsv/yii2-jwt-auth "@dev"
-
Add to config/web.php into
components
section$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 ], ], ];
-
Change method
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; }
-
Create controller
<?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, ]); } }