SDK 8
PHP 7.4
WordPress - Custom Plugin
I have a plugin to create the authorisation URL and send users to sign up - the link creation seems to work (and it used to) but now after signing up the user comes back to our callback page - this triggers a function to run to try and complete the exchange.
This used to work when we used $auth0->signup(ROUTE_URL_CALLBACK); to generate the URL, but now we want it to go to signup instead, and so are using this… $auth0->login(ROUTE_URL_CALLBACK, array( “screen_hint” => “signup” ));
Any guidance on this would be a great help.
This is the callback function…
function ****_auth0_exchange() {
global $auth0;
// Have the SDK complete the authentication flow:
$auth0->exchange(ROUTE_URL_CALLBACK);
echo "Authorising...";
}
$auth0->exchange(ROUTE_URL_CALLBACK); - generates below
Fatal error: Uncaught Auth0\SDK\Exception\StateException: Invalid state in
/home//wp-content/plugins//vendor/auth0/auth0-php/src/Exception/StateException.php:24 Stack trace:
#0 /home//wp-content/plugins//vendor/auth0/auth0-php/src/Auth0.php(322): Auth0\SDK\Exception\StateException::invalidState()
#1 /home//wp-content/plugins//src/classes/auth0.php(53): Auth0\SDK\Auth0->exchange()
#2 /home//wp-content/plugins//src/shortcodes.php(17): _auth0_exchange()
#3 /home//wp-includes/shortcodes.php(356): _auth_callback()
#4 [internal function]: do_shortcode_tag()
#5 /home//wp-includes/shortcodes.php(228): preg_replace_callback()
#6 /home//wp-includes/ in /home//wp-content/plugins/****/vendor/auth0/auth0-php/src/Exception/StateException.php on line 24
Hi @paulrileydnrg
An InvalidState exception is thrown from the PHP SDK during exchange()
when the state
parameter returned by Auth0 doesn’t match the temporary cookie stored on the client when login()
is fired before the redirect. This means there is either an issue with the cookie getting stored properly on the client before getting redirected, being retrieved from the client during callback, or an issue with pulling the state response from the callback request.
- Check your Auth0 logs for anything out of the ordinary with the request
- Ensure you have both
code
and state
parameters the URI of your application’s callback; if there is an error parameter something is going wrong with the request, and should be in your Auth0 logs
- Use your browser dev tools to ensure the transient cookie is being set properly before the redirect
- Unrelated, but we have an
Auth0::signup()
helper method for issuing the ?screen_hint requests, so you don’t have to craft it yourself
2 Likes
Hi,
Thanks for your response.
The log seems OK, just Successful Signup and then Successful login immediately after.
Here’s the URL for our signup button…
https://XXXXXXX/authorize?
state=f237b83b2bf5b074d8c9b4fbbf2e09ea&
client_id=XXXXXXX&
redirect_uri=XXXXXXX%2Fauthorising&
scope=openid%20profile%20email&
response_mode=query&
response_type=code&
screen_hint=signup&
nonce=c7831266aef58629587ad4728d96243f&
code_challenge=Pyzcgdj9wWPE8uc4xorUzq9WRDGtVkNRxvNd2N1NtYc&
code_challenge_method=S256
I can see a cookie being created on the page, it’s not named as I’ve seen online as auth_state or similar, but a long alphanumeric name, I assume this is the cookie you mentioned?
And the callback URL seems to have the code and state
https://XXXXXXX/authorising/?
code=O2hFjjwW96fwvZ_z&
state=f237b83b2bf5b074d8c9b4fbbf2e09ea
There is no cookie when on the callback URL - is that right?
THanks again for your help
Hey again @paulrileydnrg,
Hmm, curious! That would appear to be the encrypted session cookie created by the SDK, and it appears you’re being returned the same state we’re sending to Auth0 during authorization.
Some troubleshooting that comes to mind:
- Are you certain
Auth0::login()
is only being fired once? If it’s inadvertently called twice, the state
on the client would be getting overwritten and would result in this error. (Would be unusual, but I’ve seen it come up before, and I’d be remissed if I didn’t mention it!)
- Assuming you’re using Chrome, try using the Network tab to review “doc” requests, and check the Cookies tab. You should be able to observe request and response events occurring on the cookies. Is this encrypted cookie showing in the “request” section, and being cleared in the “response”?
Beyond this, the next step I’d try is modifying the exchange()
method in the SDK in your dependencies. In your /home/wp-content/plugins/vendor/auth0/auth0-php/src/Auth0.php
file, I would temporarily change this code block:
if ($state === null || ! $this->getTransientStore()->verify('state', $state)) {
$this->clear();
throw \Auth0\SDK\Exception\StateException::invalidState();
}
to:
$tempStateLookup = $this->getTransientStore()->getStore()->get('state', '[NOT SET ON CLIENT]');
if ($state === null || ! $this->getTransientStore()->verify('state', $state)) {
$this->clear();
throw new \Auth0\SDK\Exception\StateException('Expected state to be ' . $state . '; client had ' . $tempStateLookup);
}
Obviously, you want to avoid running this in production, but this would let you know (1) if the assigned state
is, in fact, available from the client during exchange()
and (2) help figure out what the discrepancy is between what was assigned to the client and returned to your endpoint.
1 Like
Hi - thanks for this - turned out be firing twice so the state was wrong.
Appreciate the help
1 Like
No problem, glad we got it sorted!
2 Likes
Teamwork makes the dreamwork!
2 Likes