first off, i am extremely impressed with Auth0, which is impressive considering the primary PHP example leaves this out:
‘scope’ => ‘openid profile email name nickname picture’
which is critical for getting facebook/msn/yahoo to authorize. (many people i know would have given up).
my latest question: when i come to my computer the following morning and just hit a page-refresh on a page that is (was??) logged in successfully, i am getting this error in my log:
PHP Fatal error: Uncaught exception 'Auth0\SDK\Exception\CoreException' with message 'Invalid state' in /blah/blah/vendor/auth0/auth0-php/src/Auth0.php:558
Stack trace:
#0 /blah/blah/vendor/auth0/auth0-php/src/Auth0.php(480): Auth0\SDK\Auth0->exchange()
#1 /blah/blah/marksProgram.php(643): Auth0\SDK\Auth0->getUser()
#2 {main}
thrown in /blah/blah/vendor/auth0/auth0-php/src/Auth0.php on line 558
in other words, i have a link that looks like this:
Refreshing the page is probably causing your PHP app to try to exchange the code for an access_token for a second time.
Due to how OAuth works, code can only be exchanged once for a token. state is used to verify that the recipient of the code is the same client that initiated the auth transaction, and once the code is exchanged for the access_token, the state is discarded. Any subsequent calls to /oauth/token with the same state and an already used code will fail with the Invalid state error.
Basically, refreshing the page would fall into this category.
It would be great if there was some way to “catch” this error, or at least have a PHP function that could give you the state status without actually triggering an error.
Appreciate the feedback here. The scope parameter is only needed when a login link is generated but it’s a little confusing in this context since you might only be instantiating that class once and using it in multiple places. I put through an update to the documentation here:
I’m also adding default scopes to the SDK itself to make the default authentication case work a little better:
It would be great if there was some way to “catch” this error
The getUser method is a bit overloaded but the code exchange is meant to happen only once in a designated callback URL, then a redirect to somewhere else. So, in your apps case, this URL:
In other words, whatever script/route that handles the callback should not leave the user on that route, it should redirect once it’s complete, success or otherwise.
That said, it’s the $auth0->getUser() that’s throwing the exception, not $auth0->login(). If you wrap that with a try/catch, you should be protected from that.
i can appreciate having a separate PHP logout script, but i am attempting to retrofit a number of existing PHP scripts, and so this succinct logic will probably work.
Having a separate script file for logout isn’t necessary but I would recommend separating the callback somehow, whether that’s a separate script/route or even just a specific URL parameter so you can keep that logic separate.
What you’ve got here is a good start but if you don’t handle that exception somehow, failing state will fall through, redirect to login, pick up SSO, and might end up in an infinite redirect. So I might recommend stopping the process at the exception catch and maybe prompt the user to login again (might could include a redirect to logout of Auth0 first).
You can see how this could get a bit tangled with all this logic in one place!