Skip to content

Commit

Permalink
Merge pull request #2 from dmstr/feature/handle-id-and-refresh-tokens
Browse files Browse the repository at this point in the history
Feature/handle id and refresh tokens
  • Loading branch information
eluhr authored Jan 26, 2024
2 parents 22acd5b + bc5140e commit cbf97b6
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 13 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
],
"require": {
"yiisoft/yii2": "^2.0.47",
"lcobucci/jwt": "^4.2"
"lcobucci/jwt": "^5.1"
},
"autoload": {
"psr-4": {
Expand Down
37 changes: 37 additions & 0 deletions src/components/BaseTokenManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ abstract class BaseTokenManager extends Component implements TokenManagerInterfa
*/
protected UnencryptedToken $_token;

protected UnencryptedToken $_token_id;

protected UnencryptedToken $_token_refresh;

protected const TYPE_TOKEN = "token";

protected const TYPE_TOKEN_ID = "token_id";

protected const TYPE_TOKEN_REFRESH = "token_refresh";


/**
* @inheritdoc
*/
Expand All @@ -33,6 +44,16 @@ public function getToken(): UnencryptedToken
return $this->_token;
}

public function getIdToken(): UnencryptedToken
{
return $this->_token_id;
}

public function getRefreshToken(): UnencryptedToken
{
return $this->_token_refresh;
}

/**
* @inheritdoc
*/
Expand All @@ -41,6 +62,22 @@ public function setToken(UnencryptedToken $token): void
$this->_token = $token;
}

/**
* @inheritdoc
*/
public function setIdToken(UnencryptedToken $token): void
{
$this->_token_id = $token;
}

/**
* @inheritdoc
*/
public function setRefreshToken(UnencryptedToken $token): void
{
$this->_token_refresh = $token;
}

/**
* @inheritdoc
*/
Expand Down
133 changes: 124 additions & 9 deletions src/components/TokenManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,18 @@ class TokenManager extends BaseTokenManager implements TokenManagerStorageInterf
*/
public string $tokenManagerSessionKey = __CLASS__;

/**
* session key for id_token
* @var string
*/
public string $tokenManagerSessionKey_id = __CLASS__ . "_token_id";

/**
* session key for refresh_token
* @var string
*/
public string $tokenManagerSessionKey_refresh = __CLASS__ . "_token_refresh";

/**
* Static storage fallback if user session is disabled
*
Expand All @@ -62,6 +74,20 @@ public function init()
$this->_session = Instance::ensure($this->sessionComponentId, Session::class);
}

/**
* Convenience method to set all 3 tokens at the same time.
* @param UnencryptedToken $token
* @param UnencryptedToken $id_token
* @param UnencryptedToken $refresh_token
* @return void
*/
public function setTokens(UnencryptedToken $token, UnencryptedToken $id_token, UnencryptedToken $refresh_token): void
{
self::setToken($token);
self::setIdToken($id_token);
self::setRefreshToken($refresh_token);
}

/**
* @inheritdoc
*/
Expand All @@ -71,6 +97,24 @@ public function setToken(UnencryptedToken $token): void
$this->persistTokenInStorage();
}

/**
* @inheritdoc
*/
public function setIdToken(UnencryptedToken $token): void
{
parent::setIdToken($token);
$this->persistTokenInStorage(self::TYPE_TOKEN_ID);
}

/**
* @inheritdoc
*/
public function setRefreshToken(UnencryptedToken $token): void
{
parent::setRefreshToken($token);
$this->persistTokenInStorage(self::TYPE_TOKEN_REFRESH);
}

/**
* @inheritdoc
*
Expand Down Expand Up @@ -108,36 +152,107 @@ public function getToken(): UnencryptedToken
return parent::getToken();
}

/**
* @throws LoadTokenException
*/
public function getIdToken(): UnencryptedToken
{
if (!$this->loadTokenFromStorage(self::TYPE_TOKEN_ID)) {
throw new LoadTokenException('Error while loading id token data');
}
return parent::getIdToken();
}

/**
* @throws LoadTokenException
*/
public function getRefreshToken(): UnencryptedToken
{
if (!$this->loadTokenFromStorage(self::TYPE_TOKEN_REFRESH)) {
throw new LoadTokenException('Error while loading refresh token data');
}
return parent::getRefreshToken();
}

/**
* Persist set token in (session) storage
*
* @return void
*/
public function persistTokenInStorage(): void
public function persistTokenInStorage($type = self::TYPE_TOKEN): void
{
if ($this->isStorageEnabled()) {
$this->getSession()->set($this->tokenManagerSessionKey, $this->_token);
switch ($type) {
case self::TYPE_TOKEN:
$this->getSession()->set($this->tokenManagerSessionKey, $this->_token);
break;
case self::TYPE_TOKEN_ID:
$this->getSession()->set($this->tokenManagerSessionKey_id, $this->_token_id);
break;
case self::TYPE_TOKEN_REFRESH:
$this->getSession()->set($this->tokenManagerSessionKey_refresh, $this->_token_refresh);
break;
}
} else {
static::$_storage['token'] = $this->_token;
switch ($type) {
case self::TYPE_TOKEN:
static::$_storage[self::TYPE_TOKEN] = $this->_token;
break;
case self::TYPE_TOKEN_ID:
static::$_storage[self::TYPE_TOKEN_ID] = $this->_token_id;
break;
case self::TYPE_TOKEN_REFRESH:
static::$_storage[self::TYPE_TOKEN_REFRESH] = $this->_token_refresh;
break;
}
}
}

/**
* Load saved token from (session) storage
* Load saved token (Only Access Token) from (session) storage
*
* @return bool
* @throws LoadTokenException
*/
public function loadTokenFromStorage(): bool
public function loadTokenFromStorage($type = self::TYPE_TOKEN): bool
{
/** @var UnencryptedToken|null $token */
if ($this->isStorageEnabled()) {
$token = $this->getSession()->get($this->tokenManagerSessionKey);
switch ($type) {
case self::TYPE_TOKEN:
$token = $this->getSession()->get($this->tokenManagerSessionKey);
break;
case self::TYPE_TOKEN_ID:
$token = $this->getSession()->get($this->tokenManagerSessionKey_id);
break;
case self::TYPE_TOKEN_REFRESH:
$token = $this->getSession()->get($this->tokenManagerSessionKey_refresh);
break;
}
} else {
$token = static::$_storage['token'] ?? null;
switch ($type) {
case self::TYPE_TOKEN:
$token = static::$_storage[self::TYPE_TOKEN] ?? null;
break;
case self::TYPE_TOKEN_ID:
$token = static::$_storage[self::TYPE_TOKEN_ID] ?? null;
break;
case self::TYPE_TOKEN_REFRESH:
$token = static::$_storage[self::TYPE_TOKEN_REFRESH] ?? null;
break;
}
}
if ($token instanceof UnencryptedToken) {
$this->setToken($token);
switch ($type) {
case self::TYPE_TOKEN:
$this->setToken($token);
break;
case self::TYPE_TOKEN_ID:
$this->setIdToken($token);
break;
case self::TYPE_TOKEN_REFRESH:
$this->setRefreshToken($token);
break;
}
return true;
} else {
if (!$this->suppressExceptions) {
Expand Down
14 changes: 13 additions & 1 deletion src/event/TokenManagerEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@ class TokenManagerEvent extends Event
const EVENT_AFTER_SET_TOKEN = 'afterSetToken';

protected UnencryptedToken $token;
protected UnencryptedToken $token_id;
protected UnencryptedToken $token_refresh;

public function __construct(UnencryptedToken $token, $config = [])
public function __construct(UnencryptedToken $token, UnencryptedToken $_token_id, UnencryptedToken $_token_refresh, $config = [])
{
$this->token = $token;
$this->token_id = $_token_id;
$this->token_refresh = $_token_refresh;

parent::__construct($config);
}
Expand All @@ -28,4 +32,12 @@ public function getToken(): UnencryptedToken
return $this->token;
}

public function getIdToken(): UnencryptedToken
{
return $this->token_id;
}
public function getRefreshToken(): UnencryptedToken
{
return $this->token_refresh;
}
}
12 changes: 12 additions & 0 deletions src/interfaces/TokenManagerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ public function getToken(): UnencryptedToken;
*/
public function setToken(UnencryptedToken $token): void;

/**
* @param UnencryptedToken $token
* @return void
*/
public function setIdToken(UnencryptedToken $token): void;

/**
* @param UnencryptedToken $token
* @return void
*/
public function setRefreshToken(UnencryptedToken $token): void;

/**
* List of roles assigned to user via token
*
Expand Down
5 changes: 3 additions & 2 deletions src/interfaces/TokenManagerStorageInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ interface TokenManagerStorageInterface extends TokenManagerInterface
*
* @return void
*/
public function persistTokenInStorage(): void;
public function persistTokenInStorage($type): void;

/**
* Load saved token from (session) storage
*
* @param $type
* @return bool
*/
public function loadTokenFromStorage(): bool;
public function loadTokenFromStorage($type): bool;

/**
* Check whether the storage is enabled / disabled
Expand Down

0 comments on commit cbf97b6

Please sign in to comment.