CSRF token mismatch: Nuxt with Symfony (pimcore) backend

89 Views Asked by At

Setup: nuxt on docker container pimcore on another docker container

in nuxt config:

env: {
        apiDomain: process.env.VUE_APP_API_DOMAIN || "http://localhost:8000/api",
        cookieDomain: process.env.COOKIE_DOMAIN || "http://localhost",
        cookieSecure: false
    },

I have a vue(nuxt) form which retrieves the CSRF token on page load via an vuex fetch call to the server which gets the token and returns it:

$token = $this->csrfTokenManager->getToken('enquire_form')->getValue();

tokenManager type: vendor/symfony/symfony/src/Symfony/Component/Security/Csrf/CsrfTokenManager.php which uses (for storage): vendor/symfony/symfony/src/Symfony/Component/Security/Csrf/TokenStorage/SessionTokenStorage.php

call this token A above

When the form is submitted via (axios) post request,

the token manager does a check to see if token is valid: (I've modified this code with some debug stuff, apologies for the mess, but the functionality has not been changed)

public function isTokenValid(CsrfToken $token)
    {
        logger('DBG: ' . __METHOD__ . ' start');

        logger('DBG: ' . __METHOD__ . ' namespace=' . $this->getNamespace()); // empty for both pim + PM

        logger('DBG: ' . __METHOD__ . ' token.getId=' . $token->getId());

        $namespacedId = $this->getNamespace().$token->getId();

        logger('DBG: ' . __METHOD__ . ' namespacedId=' . $namespacedId);

        logger('DBG: ' . __METHOD__ . ' storage.class=' . get_class($this->storage));

        if (!$this->storage->hasToken($namespacedId)) {
            logger('DBG: ' . __METHOD__ . ' no token in storage');

            return false;
        }

        logger('DBG: ' . __METHOD__ . ' STORAGE HAS TOKEN');

        $storageToken = $this->storage->getToken($namespacedId);
        logger('DBG: ' . __METHOD__ . ' storageToken=' . $storageToken);

        $tokenValue = $token->getValue();
        logger('DBG: ' . __METHOD__ . ' tokenValue=' . $tokenValue);

        return hash_equals($storageToken, $tokenValue);

        //return hash_equals($this->storage->getToken($namespacedId), $token->getValue());
    }

enter image description here

From the log output - can be seen that the storage value being retrieved (on SessionTokenStorage, or $this->storage-getToken()) is different for the POST request to what was last created during the GET request (to create the token to start with). And therefor the check is failing ...

Any help much appreciated

1

There are 1 best solutions below

0
On

OK update - turns out this was due to the session on the server not being correct, due to the PHPSESSID cookie not being passed during the axios call.

The cookie-universal-nuxt lib was useful here for getting the cookies in nuxt (vue-cookies doesn't seem to have access to the PHPSESSID cookie for some reason).