Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • i.vasilenko/symfony-trainee
1 result
Show changes
Commits on Source (2)
Showing
with 318 additions and 6 deletions
......@@ -13,6 +13,7 @@
"doctrine/doctrine-bundle": "^2.12",
"doctrine/doctrine-migrations-bundle": "^3.3",
"doctrine/orm": "^3.2",
"gesdinet/jwt-refresh-token-bundle": "^1.3",
"lexik/jwt-authentication-bundle": "^3.0",
"nelmio/api-doc-bundle": "^4.27",
"nelmio/cors-bundle": "^2.5",
......
......@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "8b6f0b619e1fcafec2ca3e3ae288f1c0",
"content-hash": "5df50b18b564c984ccc4431f60ca2151",
"packages": [
{
"name": "api-platform/core",
......@@ -1484,6 +1484,86 @@
],
"time": "2023-10-06T06:47:41+00:00"
},
{
"name": "gesdinet/jwt-refresh-token-bundle",
"version": "v1.3.0",
"source": {
"type": "git",
"url": "https://github.com/markitosgv/JWTRefreshTokenBundle.git",
"reference": "83d687cc461b4bdae9ffc6efda97464093cae739"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/markitosgv/JWTRefreshTokenBundle/zipball/83d687cc461b4bdae9ffc6efda97464093cae739",
"reference": "83d687cc461b4bdae9ffc6efda97464093cae739",
"shasum": ""
},
"require": {
"doctrine/persistence": "^1.3.3|^2.0|^3.0",
"lexik/jwt-authentication-bundle": "^2.0|^3.0",
"php": ">=7.4",
"symfony/config": "^4.4|^5.4|^6.0|^7.0",
"symfony/console": "^4.4|^5.4|^6.0|^7.0",
"symfony/dependency-injection": "^4.4|^5.4|^6.0|^7.0",
"symfony/deprecation-contracts": "^2.1|^3.0",
"symfony/event-dispatcher": "^4.4|^5.4|^6.0|^7.0",
"symfony/http-foundation": "^4.4|^5.4|^6.0|^7.0",
"symfony/http-kernel": "^4.4|^5.4|^6.0|^7.0",
"symfony/polyfill-php80": "^1.15",
"symfony/property-access": "^4.4|^5.4|^6.0|^7.0",
"symfony/security-bundle": "^4.4|^5.4|^6.0|^7.0",
"symfony/security-core": "^4.4|^5.4|^6.0|^7.0",
"symfony/security-http": "^4.4|^5.4|^6.0|^7.0"
},
"conflict": {
"doctrine/mongodb-odm": "<2.2",
"doctrine/orm": "<2.7"
},
"require-dev": {
"doctrine/annotations": "^1.13|^2.0",
"doctrine/cache": "^1.11|^2.0",
"doctrine/mongodb-odm": "^2.2",
"doctrine/orm": "^2.7",
"matthiasnoback/symfony-config-test": "^4.2|^5.0",
"matthiasnoback/symfony-dependency-injection-test": "^4.2|^5.0",
"phpunit/phpunit": "^9.5",
"symfony/cache": "^4.4|^5.4|^6.0|^7.0",
"symfony/security-guard": "^4.4|^5.4"
},
"type": "symfony-bundle",
"extra": {
"branch-alias": {
"dev-master": "1.x-dev"
}
},
"autoload": {
"psr-4": {
"Gesdinet\\JWTRefreshTokenBundle\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Marcos Gómez Vilches",
"email": "marcos@gesdinet.com"
}
],
"description": "Implements a refresh token system over Json Web Tokens in Symfony",
"keywords": [
"jwt refresh token bundle symfony json web"
],
"support": {
"issues": "https://github.com/markitosgv/JWTRefreshTokenBundle/issues",
"source": "https://github.com/markitosgv/JWTRefreshTokenBundle/tree/v1.3.0"
},
"time": "2024-01-10T19:40:34+00:00"
},
{
"name": "lcobucci/clock",
"version": "3.2.0",
......
......@@ -16,4 +16,5 @@ return [
DAMA\DoctrineTestBundle\DAMADoctrineTestBundle::class => ['test' => true],
Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true],
Liip\TestFixturesBundle\LiipTestFixturesBundle::class => ['dev' => true, 'test' => true],
Gesdinet\JWTRefreshTokenBundle\GesdinetJWTRefreshTokenBundle::class => ['all' => true],
];
gesdinet_jwt_refresh_token:
refresh_token_class: App\Entity\RefreshToken
......@@ -24,6 +24,9 @@ security:
pattern: ^/api
stateless: true
jwt: ~
entry_point: jwt
refresh_jwt:
check_path: api_refresh
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
......
......@@ -5,4 +5,7 @@ controllers:
type: attribute
api_login:
path: /api/login
\ No newline at end of file
path: /api/login
api_refresh:
path: /api/refresh
\ No newline at end of file
gesdinet_jwt_refresh_token:
path: /api/token/refresh
......@@ -72,4 +72,20 @@ services:
acme_api.event.jwt_expired_listener:
class: App\Listeners\JwtListener
tags:
- { name: kernel.event_listener, event: lexik_jwt_authentication.on_jwt_expired, method: onJWTExpired }
\ No newline at end of file
- { name: kernel.event_listener, event: lexik_jwt_authentication.on_jwt_expired, method: onJWTExpired }
gesdinet.jwtrefreshtoken.send_token:
class: App\Listeners\JwtRefreshListener
arguments:
- '@gesdinet.jwtrefreshtoken.refresh_token_manager'
- '%gesdinet_jwt_refresh_token.ttl%'
- '@request_stack'
- '%gesdinet_jwt_refresh_token.token_parameter_name%'
- '%gesdinet_jwt_refresh_token.single_use%'
- '@gesdinet.jwtrefreshtoken.refresh_token_generator'
- '@gesdinet.jwtrefreshtoken.request.extractor.chain'
- '%gesdinet_jwt_refresh_token.cookie%'
- '%gesdinet_jwt_refresh_token.return_expiration%'
- '%gesdinet_jwt_refresh_token.return_expiration_parameter_name%'
tags:
- { name: kernel.event_listener, event: lexik_jwt_authentication.on_authentication_success, method: attachRefreshToken }
\ No newline at end of file
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20240827103922 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE SEQUENCE refresh_tokens_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE TABLE refresh_tokens (id INT NOT NULL, refresh_token VARCHAR(128) NOT NULL, username VARCHAR(255) NOT NULL, valid TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE UNIQUE INDEX UNIQ_9BACE7E1C74F2195 ON refresh_tokens (refresh_token)');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE SCHEMA public');
$this->addSql('DROP SEQUENCE refresh_tokens_id_seq CASCADE');
$this->addSql('DROP TABLE refresh_tokens');
}
}
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gesdinet\JWTRefreshTokenBundle\Entity\RefreshToken as BaseRefreshToken;
#[ORM\Entity]
#[ORM\Table(name: 'refresh_tokens')]
class RefreshToken extends BaseRefreshToken
{
}
<?php
namespace App\Listeners;
use App\Service\Response\Classes\Response;
use Gesdinet\JWTRefreshTokenBundle\Event\RefreshAuthenticationFailureEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class AuthenticationFailure implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
'gesdinet.refresh_token_failure' => 'failureRefresh'
];
}
/**
* Ошибка refresh токена
*
* @param RefreshAuthenticationFailureEvent $event
*
* @return void
* @throws \JsonException
*/
public function failureRefresh(RefreshAuthenticationFailureEvent $event): void
{
$responseDto = new Response();
$responseDto->addError('Refresh токен не валиден');
$response = $event->getResponse();
$response->setContent($responseDto->getResponse()->getContent());
}
}
\ No newline at end of file
<?php
namespace App\Listeners;
use App\Service\Response\Classes\TokenResponse;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Core\User\UserInterface;
use Gesdinet\JWTRefreshTokenBundle\Model\RefreshTokenInterface;
use Gesdinet\JWTRefreshTokenBundle\Model\RefreshTokenManagerInterface;
use Gesdinet\JWTRefreshTokenBundle\Request\Extractor\ExtractorInterface;
use Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationSuccessEvent;
use Gesdinet\JWTRefreshTokenBundle\Generator\RefreshTokenGeneratorInterface;
use Gesdinet\JWTRefreshTokenBundle\EventListener\AttachRefreshTokenOnSuccessListener as EventListenerAttachRefreshTokenOnSuccessListener;
class JwtRefreshListener extends EventListenerAttachRefreshTokenOnSuccessListener
{
public function __construct(
RefreshTokenManagerInterface $refreshTokenManager,
$ttl,
RequestStack $requestStack,
$tokenParameterName,
$singleUse,
RefreshTokenGeneratorInterface $refreshTokenGenerator,
ExtractorInterface $extractor,
array $cookieSettings,
bool $returnExpiration,
string $returnExpirationParameterName
)
{
parent::__construct(
$refreshTokenManager,
$ttl,
$requestStack,
$tokenParameterName,
$singleUse,
$refreshTokenGenerator,
$extractor,
$cookieSettings,
$returnExpiration,
$returnExpirationParameterName
);
}
/**
* @param AuthenticationSuccessEvent $event
*
* @return void
*
* @throws \JsonException
*/
public function attachRefreshToken(AuthenticationSuccessEvent $event): void
{
$user = $event->getUser();
if (!$user instanceof UserInterface) {
return;
}
$response = new TokenResponse();
$data = $event->getData();
$response->setToken($data['data']['token']);
$request = $this->requestStack->getCurrentRequest();
if (null === $request) {
return;
}
$refreshTokenString = $this->extractor->getRefreshToken($request, $this->tokenParameterName);
if ($refreshTokenString && true === $this->singleUse) {
$refreshToken = $this->refreshTokenManager->get($refreshTokenString);
$refreshTokenString = null;
if ($refreshToken instanceof RefreshTokenInterface) {
$this->refreshTokenManager->delete($refreshToken);
}
}
if ($refreshTokenString) {
$response->setRefreshToken($refreshTokenString);
} else {
$refreshToken = $this->refreshTokenGenerator->createForUserWithTtl($user, $this->ttl);
$this->refreshTokenManager->save($refreshToken);
$refreshTokenString = $refreshToken->getRefreshToken();
$response->setRefreshToken($refreshTokenString);
}
// Set response data
$data = json_decode($response->getResponse()->getContent(), true, 512, JSON_THROW_ON_ERROR);
$event->getResponse()->setContent($response->getResponse()->getContent());
$event->setData($data);
}
}
\ No newline at end of file
......@@ -9,4 +9,7 @@ class TokenDto extends BaseDto
{
#[Groups(['data'])]
public string $token;
#[Groups(['data'])]
public string $refreshToken;
}
\ No newline at end of file
......@@ -17,8 +17,17 @@ class TokenResponse extends Response
public function setToken(string $token): void
{
$dto = new TokenDto();
$dto->token = $token;
$this->data = $dto;
if (!isset($this->data)) {
$this->data = new TokenDto();
}
$this->data->token = $token;
}
public function setRefreshToken(string $token): void
{
if (!isset($this->data)) {
$this->data = new TokenDto();
}
$this->data->refreshToken = $token;
}
}
\ No newline at end of file
......@@ -64,6 +64,20 @@
"migrations/.gitignore"
]
},
"gesdinet/jwt-refresh-token-bundle": {
"version": "1.3",
"recipe": {
"repo": "github.com/symfony/recipes-contrib",
"branch": "main",
"version": "1.0",
"ref": "2390b4ed5c195e0b3f6dea45221f3b7c0af523a0"
},
"files": [
"config/packages/gesdinet_jwt_refresh_token.yaml",
"config/routes/gesdinet_jwt_refresh_token.yaml",
"src/Entity/RefreshToken.php"
]
},
"lexik/jwt-authentication-bundle": {
"version": "3.0",
"recipe": {
......