Skip to content

Commit

Permalink
Dispatch event when token is refreshed (#89)
Browse files Browse the repository at this point in the history
  • Loading branch information
norkunas authored and markitosgv committed Mar 31, 2018
1 parent 20054ca commit 8bb51f7
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 6 deletions.
39 changes: 39 additions & 0 deletions Event/RefreshEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

/*
* This file is part of the GesdinetJWTRefreshTokenBundle package.
*
* (c) Gesdinet <http://www.gesdinet.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Gesdinet\JWTRefreshTokenBundle\Event;

use Gesdinet\JWTRefreshTokenBundle\Model\RefreshTokenInterface;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;

class RefreshEvent extends Event
{
private $refreshToken;

private $preAuthenticatedToken;

public function __construct(RefreshTokenInterface $refreshToken, PreAuthenticatedToken $preAuthenticatedToken)
{
$this->refreshToken = $refreshToken;
$this->preAuthenticatedToken = $preAuthenticatedToken;
}

public function getRefreshToken()
{
return $this->refreshToken;
}

public function getPreAuthenticatedToken()
{
return $this->preAuthenticatedToken;
}
}
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,3 +245,44 @@ If you want to revoke a single token you can use this:
```bash
php app/console gesdinet:jwt:revoke TOKEN
```

### Events

If you want to do something when token is refreshed you can listen for `gesdinet.refresh_token` event.

For example:

```php
<?php
namespace AppBundle\EventListener;
use Gesdinet\JWTRefreshTokenBundle\Event\RefreshEvent;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class LogListener implements EventSubscriberInterface
{
private $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
public function log(RefreshEvent $event)
{
$refreshToken = $event->getRefreshToken()->getRefreshToken();
$user = $event->getPreAuthenticatedToken()->getUser()->getUsername();
$this->logger->debug(sprintf('User "%s" has refreshed it\'s JWT token with refresh token "%s".', $user, $refreshToken));
}
public static function getSubscribedEvents()
{
return array(
'gesdinet.refresh_token' => 'log',
);
}
}
```
2 changes: 1 addition & 1 deletion Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ services:
gesdinet.jwtrefreshtoken:
class: Gesdinet\JWTRefreshTokenBundle\Service\RefreshToken
public: true
arguments: [ "@gesdinet.jwtrefreshtoken.authenticator", "@gesdinet.jwtrefreshtoken.user_provider", "@lexik_jwt_authentication.handler.authentication_success", "@lexik_jwt_authentication.handler.authentication_failure", "@gesdinet.jwtrefreshtoken.refresh_token_manager", "%gesdinet_jwt_refresh_token.ttl%", "%gesdinet_jwt_refresh_token.security.firewall%", "%gesdinet_jwt_refresh_token.ttl_update%" ]
arguments: [ "@gesdinet.jwtrefreshtoken.authenticator", "@gesdinet.jwtrefreshtoken.user_provider", "@lexik_jwt_authentication.handler.authentication_success", "@lexik_jwt_authentication.handler.authentication_failure", "@gesdinet.jwtrefreshtoken.refresh_token_manager", "%gesdinet_jwt_refresh_token.ttl%", "%gesdinet_jwt_refresh_token.security.firewall%", "%gesdinet_jwt_refresh_token.ttl_update%", "@event_dispatcher" ]

gesdinet.jwtrefreshtoken.user_provider:
class: Gesdinet\JWTRefreshTokenBundle\Security\Provider\RefreshTokenProvider
Expand Down
9 changes: 8 additions & 1 deletion Service/RefreshToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

namespace Gesdinet\JWTRefreshTokenBundle\Service;

use Gesdinet\JWTRefreshTokenBundle\Event\RefreshEvent;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Lexik\Bundle\JWTAuthenticationBundle\Security\Http\Authentication\AuthenticationSuccessHandler;
use Lexik\Bundle\JWTAuthenticationBundle\Security\Http\Authentication\AuthenticationFailureHandler;
Expand Down Expand Up @@ -38,7 +40,9 @@ class RefreshToken

private $ttlUpdate;

public function __construct(RefreshTokenAuthenticator $authenticator, RefreshTokenProvider $provider, AuthenticationSuccessHandler $successHandler, AuthenticationFailureHandler $failureHandler, RefreshTokenManagerInterface $refreshTokenManager, $ttl, $providerKey, $ttlUpdate)
private $eventDispatcher;

public function __construct(RefreshTokenAuthenticator $authenticator, RefreshTokenProvider $provider, AuthenticationSuccessHandler $successHandler, AuthenticationFailureHandler $failureHandler, RefreshTokenManagerInterface $refreshTokenManager, $ttl, $providerKey, $ttlUpdate, EventDispatcherInterface $eventDispatcher)
{
$this->authenticator = $authenticator;
$this->provider = $provider;
Expand All @@ -48,6 +52,7 @@ public function __construct(RefreshTokenAuthenticator $authenticator, RefreshTok
$this->ttl = $ttl;
$this->providerKey = $providerKey;
$this->ttlUpdate = $ttlUpdate;
$this->eventDispatcher = $eventDispatcher;
}

/**
Expand Down Expand Up @@ -86,6 +91,8 @@ public function refresh(Request $request)
$this->refreshTokenManager->save($refreshToken);
}

$this->eventDispatcher->dispatch('gesdinet.refresh_token', new RefreshEvent($refreshToken, $preAuthenticatedToken));

return $this->successHandler->onAuthenticationSuccess($request, $preAuthenticatedToken);
}
}
9 changes: 5 additions & 4 deletions spec/Service/RefreshTokenSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,21 @@
use Lexik\Bundle\JWTAuthenticationBundle\Security\Http\Authentication\AuthenticationSuccessHandler;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;

class RefreshTokenSpec extends ObjectBehavior
{
public function let(RefreshTokenAuthenticator $authenticator, RefreshTokenProvider $provider, AuthenticationSuccessHandler $successHandler, AuthenticationFailureHandler $failureHandler, RefreshTokenManagerInterface $refreshTokenManager, TokenInterface $token, UserProviderInterface $userProvider, $ttl, $providerKey, $ttlUpdate)
public function let(RefreshTokenAuthenticator $authenticator, RefreshTokenProvider $provider, AuthenticationSuccessHandler $successHandler, AuthenticationFailureHandler $failureHandler, RefreshTokenManagerInterface $refreshTokenManager, TokenInterface $token, UserProviderInterface $userProvider, $ttl, $providerKey, $ttlUpdate, EventDispatcherInterface $eventDispatcher)
{
$ttl = 2592000;
$ttlUpdate = false;
$providerKey = 'testkey';

$this->beConstructedWith($authenticator, $provider, $successHandler, $failureHandler, $refreshTokenManager, $ttl, $providerKey, $ttlUpdate);
$this->beConstructedWith($authenticator, $provider, $successHandler, $failureHandler, $refreshTokenManager, $ttl, $providerKey, $ttlUpdate, $eventDispatcher);
}

public function it_is_initializable()
Expand All @@ -42,9 +43,9 @@ public function it_refresh_token(Request $request, $refreshTokenManager, $authen
$this->refresh($request);
}

public function it_refresh_token_with_ttl_update(RefreshTokenProvider $provider, AuthenticationSuccessHandler $successHandler, AuthenticationFailureHandler $failureHandler, Request $request, $refreshTokenManager, $authenticator, $token, PreAuthenticatedToken $preAuthenticatedToken, RefreshTokenInterface $refreshToken)
public function it_refresh_token_with_ttl_update(RefreshTokenProvider $provider, AuthenticationSuccessHandler $successHandler, AuthenticationFailureHandler $failureHandler, Request $request, $refreshTokenManager, $authenticator, $token, PreAuthenticatedToken $preAuthenticatedToken, RefreshTokenInterface $refreshToken, EventDispatcherInterface $eventDispatcher)
{
$this->beConstructedWith($authenticator, $provider, $successHandler, $failureHandler, $refreshTokenManager, 2592000, 'testkey', true);
$this->beConstructedWith($authenticator, $provider, $successHandler, $failureHandler, $refreshTokenManager, 2592000, 'testkey', true, $eventDispatcher);

$authenticator->createToken(Argument::any(), Argument::any())->willReturn($token);
$authenticator->authenticateToken(Argument::any(), Argument::any(), Argument::any())->willReturn($preAuthenticatedToken);
Expand Down

0 comments on commit 8bb51f7

Please sign in to comment.