Skip to content

Instantly share code, notes, and snippets.

@eusonlito
Last active April 17, 2023 11:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eusonlito/2dcb0223194120857b913824f660d3b5 to your computer and use it in GitHub Desktop.
Save eusonlito/2dcb0223194120857b913824f660d3b5 to your computer and use it in GitHub Desktop.
Simple PHP JWT Service over https://github.com/lcobucci/jwt
<?php declare(strict_types=1);
namespace App\Services\Jwt;
use DateTimeImmutable;
use Lcobucci\JWT\Encoding\ChainedFormatter;
use Lcobucci\JWT\Encoding\JoseEncoder;
use Lcobucci\JWT\Signer\Key\InMemory;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\Token\Builder;
class Token
{
/**
* @param string $url
* @param string|int $id
* @param string $expires
*
* @return string
*/
public static function get(string $url, string|int $id, string $expires): string
{
return static::builder()
->issuedBy($url)
->permittedFor($url)
->identifiedBy(static::identifiedBy($id))
->issuedAt(static::issuedAt())
->expiresAt(static::expiresAt($expires))
->getToken(...static::getToken())
->toString();
}
/**
* @return \Lcobucci\JWT\Token\Builder
*/
protected static function builder(): Builder
{
return new Builder(new JoseEncoder(), ChainedFormatter::default());
}
/**
* @param string|int $id
*
* @return string
*/
protected static function identifiedBy(string|int $id): string
{
return base64_encode(strval($id));
}
/**
* @return \DateTimeImmutable
*/
protected static function issuedAt(): DateTimeImmutable
{
return new DateTimeImmutable();
}
/**
* @param string $expires
*
* @return \DateTimeImmutable
*/
protected static function expiresAt(string $expires): DateTimeImmutable
{
return new DateTimeImmutable($expires);
}
/**
* @return array
*/
protected static function getToken(): array
{
return [static::algorithm(), static::key()];
}
/**
* @return \Lcobucci\JWT\Signer\Hmac\Sha256
*/
protected static function algorithm(): Sha256
{
return new Sha256();
}
/**
* @return \Lcobucci\JWT\Signer\Key\InMemory
*/
protected static function key(): InMemory
{
return InMemory::plainText(random_bytes(32));
}
}
<?php declare(strict_types=1);
namespace App\Domains\UserToken\Action;
use App\Services\Jwt\Token as JwtToken;
class Create extends ActionAbstract
{
/**
* @return string
*/
public function handle(): string
{
return $this->generate();
}
/**
* @return void
*/
protected function generate(): void
{
return JwtToken::get(config('app.url'), $this->user->id, $this->expiredAt());
}
/**
* @return string
*/
protected function expiredAt(): string
{
return date('Y-m-d H:i:s', time() + config('jwt.ttl'));
}
}
<?php declare(strict_types=1);
namespace App\Services\Jwt;
use Lcobucci\JWT\Encoding\CannotDecodeContent;
use Lcobucci\JWT\Encoding\JoseEncoder;
use Lcobucci\JWT\Token\InvalidTokenStructure;
use Lcobucci\JWT\Token\Parser;
use Lcobucci\JWT\Token\UnsupportedHeaderFound;
class Validate
{
/**
* @param ?string $token
*
* @return ?string
*/
public static function get(?string $token): ?string
{
if (empty($token) || empty($jti = static::jti($token))) {
return null;
}
return base64_decode($jti, true);
}
/**
* @param string $token
*
* @return ?string
*/
protected static function jti(string $token): ?string
{
try {
return static::parser()->parse($token)->claims()->get('jti');
} catch (CannotDecodeContent|InvalidTokenStructure|UnsupportedHeaderFound $e) {
return null;
}
}
/**
* @return \Lcobucci\JWT\Token\Parser
*/
protected static function parser(): Parser
{
return new Parser(new JoseEncoder());
}
}
<?php declare(strict_types=1);
namespace App\Domains\UserToken\Action;
use InvalidArgumentException;
use App\Domains\User\Model\User as UserModel;
use App\Services\Jwt\Validate as JwtValidate;
class Validate extends ActionAbstract
{
/**
* @return void
*/
public function handle(): void
{
$this->validate();
}
/**
* @return void
*/
protected function validate(): void
{
$this->user = UserModel::query()->byId($this->id())->firstOrFail();
}
/**
* @return int
*/
protected function id(): int
{
$id = JwtValidate::get($this->request->bearerToken());
if (is_null($id)) {
throw new InvalidArgumentException();
}
return intval($id);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment