PHP code example of yawaweb / yii2-jwt

1. Go to this page and download the library: Download yawaweb/yii2-jwt library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

yawaweb / yii2-jwt example snippets


 
    CREATE TABLE `user_refresh_tokens` (
        `user_refresh_tokenID` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
        `urf_userID` INT(10) UNSIGNED NOT NULL,
        `urf_token` VARCHAR(1000) NOT NULL,
        `urf_ip` VARCHAR(50) NOT NULL,
        `urf_user_agent` VARCHAR(1000) NOT NULL,
        `urf_created` DATETIME NOT NULL COMMENT 'UTC',
        PRIMARY KEY (`user_refresh_tokenID`)
    )
    COMMENT='For JWT authentication process';

 
return [
    ...
    'jwt' => [
        'issuer' => 'https://api.example.com',  //name of your project (for information only)
        'audience' => 'https://example.com',  //description of the audience, eg. the website using the authentication (for info only)
        'id' => 'AMqey0yAVrqmhR82RMlWB3zqMpvRP0zaaOheEeq2tmmcEtRYNj',  //a unique identifier for the JWT, typically a random string
        'expire' => '+1 hour',  //the short-lived JWT token is here set to expire after 1 Hours.
        'request_time' => '+5 seconds', //the time between the two requests. (optional)
    ],
    ...
]; 


$config = [
    'components' => [
        ...
        'jwt' => [
            'class' => \kaabar\jwt\Jwt::class,
            'key' => 'SECRET-KEY',  //typically a long random string
        ],
        ...
    ],
];


public function behaviors() {
    $behaviors = parent::behaviors();

    $behaviors['authenticator'] = [
        'class' => \kaabar\jwt\JwtHttpBearerAuth::class,
        'except' => [
            'login',
            'options',
        ],
    ];

    return $behaviors;
}


private function generateJwt(\app\models\User $user) {
    $jwt = Yii::$app->jwt;
    $signer = $jwt->getSigner('HS256');
    $key = $jwt->getKey();

    //use DateTimeImmutable;
    $now   = new DateTimeImmutable();
    
    $jwtParams = Yii::$app->params['jwt'];

    $token = $jwt->getBuilder()
        // Configures the issuer (iss claim)
        ->issuedBy($jwtParams['issuer'])
        // Configures the audience (aud claim)
        ->permittedFor($jwtParams['audience'])
        // Configures the id (jti claim)
        ->identifiedBy($jwtParams['id'], true)
        // 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->modify($jwtParams['request_time']))
        // Configures the expiration time of the token (exp claim)
        ->expiresAt($now->modify($jwtParams['expire']))
        // Configures a new claim, called "uid"
        ->withClaim('uid', $user->id)
        // Builds a new token
        ->getToken($signer, $key);

    return $token->toString();
}

/**
 * @throws yii\base\Exception
*/
private function generateRefreshToken(\app\models\User $user, \app\models\User $impersonator = null): \app\models\UserRefreshToken {
    $refreshToken = Yii::$app->security->generateRandomString(200);

    // TODO: Don't always regenerate - you could reuse existing one if user already has one with same IP and user agent
    $userRefreshToken = new \app\models\UserRefreshToken([
        'urf_userID' => $user->id,
        'urf_token' => $refreshToken,
        'urf_ip' => Yii::$app->request->userIP,
        'urf_user_agent' => Yii::$app->request->userAgent,
        'urf_created' => gmdate('Y-m-d H:i:s'),
    ]);
    if (!$userRefreshToken->save()) {
        throw new \yii\web\ServerErrorHttpException('Failed to save the refresh token: '. $userRefreshToken->getErrorSummary(true));
    }

    // Send the refresh-token to the user in a HttpOnly cookie that Javascript can never read and that's limited by path
    Yii::$app->response->cookies->add(new \yii\web\Cookie([
        'name' => 'refresh-token',
        'value' => $refreshToken,
        'httpOnly' => true,
        'sameSite' => 'none',
        'secure' => true,
        'path' => '/v1/auth/refresh-token',  //endpoint URI for renewing the JWT token using this refresh-token, or deleting refresh-token
    ]));

    return $userRefreshToken;
}


public function actionLogin() {
    $model = new \app\models\LoginForm();
    if ($model->load(Yii::$app->request->getBodyParams()) && $model->login()) {
        $user = Yii::$app->user->identity;

        $token = $this->generateJwt($user);
    
        return [
            'user' => $user,
            'token' => (string) $token,
        ];
    } 
    else 
    {
        $model->validate();
        return $model;
    }
}




public function actionRefreshToken() {

    $refreshToken = Yii::$app->request->cookies->getValue('refresh-token', false);
    if (!$refreshToken) {
        return new \yii\web\UnauthorizedHttpException('No refresh token found.');
    }

    $userRefreshToken = \app\models\UserRefreshToken::findOne(['urf_token' => $refreshToken]);

    if (Yii::$app->request->getMethod() == 'POST') {
        // Getting new JWT after it has expired
        if (!$userRefreshToken) {
            return new \yii\web\UnauthorizedHttpException('The refresh token no longer exists.');
        }

        $user = \app\models\User::find()  //adapt this to your needs
            ->where(['userID' => $userRefreshToken->urf_userID])
            ->andWhere(['not', ['usr_status' => 'inactive']])
            ->one();
        if (!$user) {
            $userRefreshToken->delete();
            return new \yii\web\UnauthorizedHttpException('The user is inactive.');
        }

        $token = $this->generateJwt($user);

        return [
            'status' => 'ok',
            'token' => (string) $token,
        ];

    } elseif (Yii::$app->request->getMethod() == 'DELETE') {
        // Logging out
        if ($userRefreshToken && !$userRefreshToken->delete()) {
            return new \yii\web\ServerErrorHttpException('Failed to delete the refresh token.');
        }

        return ['status' => 'ok'];
    } else {
        return new \yii\web\UnauthorizedHttpException('The user is inactive.');
    }
}



public static function findIdentityByAccessToken($token, $type = null) {
    return static::find()
        ->where(['userID' => (string) $token->getClaim('uid') ])
        ->andWhere(['<>', 'usr_status', 'inactive'])  //adapt this to your needs
        ->one();
}



    public function afterSave($isInsert, $changedOldAttributes) {
		// Purge the user tokens when the password is changed
		if (array_key_exists('usr_password', $changedOldAttributes)) {
			\app\models\UserRefreshToken::deleteAll(['urf_userID' => $this->userID]);
		}

		return parent::afterSave($isInsert, $changedOldAttributes);
	}