1

I am having trouble in making authentication work using an external frontend ( vue ) with my symfony app. The main problem is the "Invalid CSRF token" error. I have a login form in vue which sends an object containing the username, password, and the csrf token ( which I get from symfony tokengenerator ). I have a custom authenticator where I create the user passport and add the token to it.

public function authenticate(Request $request): PassportInterface
    {
        $username = $request->request->get('username', '');

        $request->getSession()->set(Security::LAST_USERNAME, $username);
        $this->logger->info('The token is', [$request->get('_csrf_token')]);
        $passport =  new Passport(
            new UserBadge($username),
            new PasswordCredentials($request->request->get('password', '')),
        );
        $passport->addBadge(new CsrfTokenBadge('authenticate', $request->get('_csrf_token'))); 
        return $passport;
    }

It makes it through to the AuthenticationManager.php, where it enters the executeAuthenticator method. The error comes after the CheckPassportEvent is dispatched, from CSRFProtectionListener. It fails on the if (false === $this->csrfTokenManager->isTokenValid($csrfToken)).

I have tried to get the tokenmanager instance inside of my authenticator and create the token there and add it to the passport.

$token = $this->csrfTokenManager->getToken('authenticate'); $passport->addBadge(new CsrfTokenBadge($token->getId(), $token->getValue()));

This lets me get past the authentication, but immediately afterwards, when it redirects to the next path, it gives me an error "Access denied, the user is not fully authenticated; redirecting to authentication entry point.". After some debugging, it seems that the token storage is empty ( the token is saved to the storage when the getToken() method is called ).

When I do the authentication with the twig template, it works flawlessly. How exactly {{ csrf_token('authenticate') }} makes and handles the token I do not understand. Any input would be appreciated.

2 Answers 2

0

You have to pass the Authenticationintention as a string. In your example its "authenticate".

$passport->addBadge(new CsrfTokenBadge(' ---> authenticate <--- ', $request->get('_csrf_token'))); 

To check it you should use a code like this:

if (false === $this->csrfTokenManager->isTokenValid(new CsrfToken('authenticate' $YOUR_TOKEN_HERE))

or from a controller:

$this->isCsrfTokenValid('authenticate', $YOUR_TOKEN_HERE)
enter code here
Sign up to request clarification or add additional context in comments.

3 Comments

When I do it by default with ->get('_csrf_token') the isTokenValid returns me always false. In my controller, i send the token to vue with following code : ` public function GenerateToken() { $token = $this->tokenGenerator->generateToken(); return new Response(json_encode($token)); } `
So if I generate the token in the backend, send it to vue and then submit it with the form, the isTokenValid method returns me always false ( even if I implement randomize like in the token manager ). If I generate the token in the authenticator, the the login works, but making any request to any other controller will return me an error that the user is not fully authenticated, which seems to happen because it cannot find the user's session ( returns null ).
Do you really use symfony version 5? Your code especially the part where you are gathering the Services (no dep injection) seems very outdated.
0

In Symfony 5 you should work with the CSRF Protection like this: In Twig, you can generate a CSRF Token with the "csrf_token" method. This Method is described here https://symfony.com/doc/current/security/csrf.html#generating-and-checking-csrf-tokens-manually.

You can validate the token in a controller using the "isCsrfTokenValid" function which lives in the controller class which you are extending.

Check this for more information: https://symfony.com/doc/4.4/security/csrf.html#generating-and-checking-csrf-tokens-manually

I think the problem is that youre using a new Symfony version but using old practicies.

1 Comment

Like I've said in my question, I have no problem running it with twig. But I want it to work with my VueJs frontend which is on a different server. I could not find any relevant guides that address this problem in symfony 5.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.