G_V G_V - 26 days ago 14
PHP Question

Symfony 2.8 Guard AbstractGuardAuthenticator, how to return a real token?

I'm playing around with

AbstractGuardAuthenticator
from the relatively new
Guard
subsystem added in Symfony 2.8.

My setup is really simple. I send a request to a protected URL which takes a username:password base64 encoded. It checks both against the database and should return a token.

The authentication successful method:

public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
//If login successful, return token
return new Response($this->tokenStorage->getToken());
}


What it returns is:

PostAuthenticationGuardToken(user="test", authenticated=true, roles="ROLE_ADVANCED,
ROLE_USER")


Now, this is what I'd expect given that the
AbstractGuardAuthenticator
defines the method for creating this token exactly like this.

public function createAuthenticatedToken(UserInterface $user, $providerKey)
{
return new PostAuthenticationGuardToken(
$user,
$providerKey,
$user->getRoles()
);
}


UPDATE 1.1:

Using the
LexikJWTAuthenticationBundle
I am now attempting to implement Json Web Tokens into my application's AbstractGuardAuthenticator. The Lexik bundle provides both a success and failure handler:
lexik_jwt_authentication.handler.authentication_success
&
lexik_jwt_authentication.handler.authentication_failure
which point at classes that get certain JWT variables injected into them. How do I hook them into
AbstractGuardAuthenticator
's success and failure handlers?

crud:
anonymous: ~
guard:
authenticators:
- app.token_authenticator
pattern: ^/database/


And the
Guard
success and failure methods

public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
if ($token = $request->headers->get('X-AUTH-TOKEN')) {
//on success, let the request continue
} else {
//If login successful, return token
return new Response($this->tokenStorage->getToken());
}
}

public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
$data = array(
'message' => strtr($exception->getMessageKey(), $exception->getMessageData())

// or to translate this message
// $this->translator->trans($exception->getMessageKey(), $exception->getMessageData())
);

return new JsonResponse($data, 403);
}


I am currently extending and merging
JWTTokenAuthenticator
with my own token authenticator instead of the
AbstractGuardAuthenticator
as both implement
GuardAuthenticatorInterface
.

Answer

I'd like to know how to return a real token, which can be used to authenticate a user instead of sending the username:password every time.

Symfony Guard Component

Guard aims at simplifying the authentication subsystem.

Before Guard, setting up custom authentication was a lot more work. You needed to create several parts/classes and make them work together. It's flexible, you can create any authentication system you want, but it needs some effort. With Guard, it becomes a lot easier, while maintaining all flexibility.

This is not the component you're looking for.

Symfony Security Token

When reading the word "token" in documentation about the Guard Component, what's referred to is an implementation of the TokenInterface. Symfony uses these implementations to keep track of the authentication state. These implementations never leave your application, it's an internal thing.

This is not the token you're looking for.

JSON Web Token

The "token" you're talking about is some pease of information a client can use to authenticate with. This can be a random string like the "access token" of OAuth 2.0 protocol, or a self-contained and signed set of information, like JSON Web Tokens (JWT).

IMHO JWT would be the most future-proof token at the moment. The Anatomy of a JSON Web Token is a good read to get familiar with JWT.

There are several bundles out there that can easily integrate JWT into your Symfony project. LexikJWTAuthenticationBundle is the most popular one right now. I suggest you have a look :)

Comments