gbksoft / yii2-tokens
Yii 2 custom tokens architecture for authorization
Installs: 2 319
Dependents: 0
Suggesters: 0
Security: 0
Stars: 2
Watchers: 3
Forks: 0
Open Issues: 0
Type:yii2-extension
Requires
- react/event-loop: ^0.4.1
- yiisoft/yii2: >=2.0.4
This package is not auto-updated.
Last update: 2024-11-09 19:19:56 UTC
README
Installation
The preferred way to install this extension is through composer.
Either run
php composer.phar require gbksoft/yii2-tokens
or add
"gbksoft/yii2-tokens": "~1.0.0"
to the require section of your composer.json
file.
Usage
Module configurations:
... 'modules' => [ 'tokens' => [ 'class' => 'gbksoft\modules\tokens\Module', 'userClass' => common\models\User::class, 'urlRulePrefix' => 'v1/', 'on beforeControllerBehavior' => function($event) { // Update behaviors on module controller "User" $event->data = common\overrides\rest\ActiveController::getDefaultBehaviors(); }, ], ], ...
Change table name for relations to users table.
Console application event for change {{%user}}
table name in module migrations example:
'on beforeUserTokenMigrateUp' => function($event) {
// $event->sender is Migration class
// $event->sender->usersTableName default value is "{{%user}}"
$event->sender->usersTableName = '{{%users}}';
}
Use controllerMap in console config:
'controllerMap' => [
'migrate' => [
'class' => 'console\controllers\MigrateController',
'migrationLookup' => [
'@console/migrations',
'@vendor/gbksoft/yii2-tokens/migrations',
]
]
],
In IdentityInterface (User model)
use yii\web\UnauthorizedHttpException; use gbksoft\modules\tokens\models\UserToken; ... class User extends ActiveRecord implements IdentityInterface { ... public $userToken; /** * @inheritdoc */ public static function findIdentityByAccessToken($token, $type = null) { /** @var $userToken \common\models\UserToken */ $userToken = UserToken::find() ->andWhere(['=', 'token', $token]) ->one(); if (!$userToken) { throw new UnauthorizedHttpException('Bad token'); } if (!$userToken->user) { throw new UnauthorizedHttpException('User not found'); } if ($userToken->user->status == self::STATUS_DELETED) { throw new UnauthorizedHttpException('This user has deleted'); } if (!$userToken->matchIp(Yii::$app->getRequest()->userIP)) { throw new UnauthorizedHttpException('Differed user token IP-s'); } if ($userToken->expired()) { throw new UnauthorizedHttpException('User token is expired'); } $user = $userToken->getUser()->one(); $user->userToken = $userToken; return $user; } ... }
Login action example
namespace api\versions\v1\controllers\user; use Yii; use yii\web\ServerErrorHttpException; use gbksoft\modules\tokens\models\UserToken; class LoginAction extends \yii\rest\CreateAction { /** * Field name of body parameter for remember * @var string */ public $rememberField = 'remember'; /** * Confirm value of body parameter for remember * @var array */ public $rememberYesValue = 'yes'; /** * Confirm value of body parameter for not remember * @var array */ public $rememberNoValue = 'no'; /** * Field name of body parameter for verify_ip * @var string */ public $verifyIpField = 'verify_ip'; /** * Confirm value of body parameter for verify_ip * @var array */ public $verifyIpYesValue = 'yes'; /** * If remember me expire time as seconds * @var integer */ public $expireSecondsRemember = 604800; // One week /** * If not remember me expire time as seconds * @var integer */ public $expireSecondsNotRemember = 3600; // One hour /** * Creates a new model. * @return \yii\db\ActiveRecordInterface the model newly created * @throws ServerErrorHttpException if there is any error when creating the model */ public function run() { if ($this->checkAccess) { call_user_func($this->checkAccess, $this->id); } /** @var $model \common\models\User */ $model = new $this->modelClass([ 'scenario' => $this->scenario, ]); /** @var $request \yii\web\Request */ $request = Yii::$app->getRequest(); $model->load($request->getBodyParams(), ''); if ($model->login($model)) { $rememberValue = $request->getBodyParam($this->rememberField); $verifyIP = ($request->getBodyParam($this->verifyIpField) == $this->verifyIpYesValue); switch ($rememberValue) { case $this->rememberYesValue: $remember = true; $seconds = $this->expireSecondsRemember; break; case $this->rememberNoValue: $remember = false; $seconds = $this->expireSecondsNotRemember; break; default: $remember = false; $seconds = UserToken::EXPIRE_DEFAULT_SECONDS; } /* @var $userToken \common\models\UserToken */ $userToken = UserToken::createForUser(Yii::$app->user->identity, $seconds, $remember, $verifyIP); if ($userToken) { return $userToken; } else { throw new ServerErrorHttpException('Failed to create the object for user token.'); } } elseif (!$model->hasErrors()) { throw new ServerErrorHttpException('Failed login.'); } return $model; } }
Console command for clear expired tokens
./yii tokens/tokens/clear-expired