verbb / social-login

A Craft CMS plugin to add SSO (Single Sign-On) user login, registration and connecting to social media platforms.
Other
5 stars 6 forks source link

Invalid callback state. State is mismatched. #10

Closed ax2000 closed 1 year ago

ax2000 commented 1 year ago

Describe the bug

When accessing the provider.getAccessToken()) method the following error is thrown:

Invalid callback state. State is mismatched. 

My template code looks like this:

{% set provider = craft.socialLogin.getProvider('auth0') %}
{{ provider.getAccessToken()) }}

The provider is a self hosted Auth0 Identy Server 4 and it uses a custom domain instead of the auth0.com service.

The login process works just fine and I am able to login via Social Login and I am redirected back to craft and I am logged in in craft successfully as well. The issue occurs when trying access the Access Token of the logged in user.

Not sure if it might have to do with being a custom auth0 provider, as some of the CP configuration fields are not relevant to us such as Region and Account. See below.

Group 133

Error Screenshot:

Screenshot 2023-06-27 at 16 43 39

Error stacktrace:

Exception: Invalid callback state. State is mismatched. in /home/lilydalebookspix/vendor/verbb/auth/src/base/OAuthProviderTrait.php:183
Stack trace:
#0 /home/lilydalebookspix/vendor/twig/twig/src/Extension/CoreExtension.php(1607): verbb\sociallogin\base\OAuthProvider->getAccessToken()
#1 /home/lilydalebookspix/vendor/craftcms/cms/src/helpers/Template.php(146): twig_get_attribute()
#2 /home/lilydalebookspix/storage/runtime/compiled_templates/9b/9b75cd0a0647053ab40352a726656c65.php(108): craft\helpers\Template::attribute()
#3 /home/lilydalebookspix/vendor/twig/twig/src/Template.php(394): __TwigTemplate_273ff2cac2910e23e444dd70358c9b16->doDisplay()
#4 /home/lilydalebookspix/vendor/twig/twig/src/Template.php(367): Twig\Template->displayWithErrorHandling()
#5 /home/lilydalebookspix/vendor/twig/twig/src/Template.php(379): Twig\Template->display()
#6 /home/lilydalebookspix/vendor/twig/twig/src/TemplateWrapper.php(40): Twig\Template->render()
#7 /home/lilydalebookspix/vendor/twig/twig/src/Environment.php(277): Twig\TemplateWrapper->render()
#8 /home/lilydalebookspix/vendor/craftcms/cms/src/web/View.php(465): Twig\Environment->render()
#9 /home/lilydalebookspix/vendor/craftcms/cms/src/web/View.php(518): craft\web\View->renderTemplate()
#10 /home/lilydalebookspix/vendor/craftcms/cms/src/web/TemplateResponseFormatter.php(56): craft\web\View->renderPageTemplate()
#11 /home/lilydalebookspix/vendor/yiisoft/yii2/web/Response.php(1098): craft\web\TemplateResponseFormatter->format()
#12 /home/lilydalebookspix/vendor/craftcms/cms/src/web/Response.php(286): yii\web\Response->prepare()
#13 /home/lilydalebookspix/vendor/yiisoft/yii2/web/Response.php(339): craft\web\Response->prepare()
#14 /home/lilydalebookspix/vendor/yiisoft/yii2/base/Application.php(390): yii\web\Response->send()
#15 /home/lilydalebookspix/public_html/index.php(12): yii\base\Application->run()
#16 {main}

Please let me know if you need me to provide any more context or any other queries that might come up as I'm not sure how easy this would be to replicate on your part.

Cheers, Alby

Steps to reproduce

  1. Successful Login via Social Login
  2. Try to parse the provider.getAccessToken()) in a template

Craft CMS version

Craft CMS 4.4.14

Plugin version

1.0.4

Multi-site?

No

Additional context

No response

engram-design commented 1 year ago

Calling getAccessToken() in your templates isn't a good idea, as that kicks off the fetching of the access token from the provider after an authorization request has been triggered. This would be the missing code or state that it's complaining about, which is expected to have been set by the authorization step. Unless of course you want users to go through the OAuth process, but this isn't the way to do that.

Are you after just the actual token value for the access token? That would be provider.getToken().

ax2000 commented 1 year ago

Thanks for your prompt response @engram-design.

So my intend was to use it as follows (and by your previous response I'm not sure if it is a good idea any more):

  1. User logs in via Social Login so gets authenticated in remote Auth0 ID4 API and Craftcms.
  2. Some of the User's data lives in an external API that only the logged in user via Social Login has access to, so I am creating an on-demand Consume client that connects to the API using the Social Login Access Token

The template that I'm building would look something like this:

{% set provider = craft.socialLogin.getProvider('auth0') %}
{% if provider and provider.isConnected() %}
  {% set token = provider.getAccessToken() %}
  {% set client = {
    base_uri: 'https://api-base-uri/',
    headers: {
      'Authorization': 'Bearer ' ~ token
    }
  } %}

  {% set data = consume(client, 'GET', 'api/User') %}

I did try with the provider.getToken() value but it's not the bearer access token needed for the consume connection and I thought that maybe the token that I'm after is the getAccessToken() one, but I'm not 100% sure though if that's the case or if my approach is right.

I did try to set up a non-on-demand Consume client using the Auth0 type, and the Consume connection to the API works just fine then, but with that method the client is authenticated using the credentials entered in the Consume area of the CP, not the logged in user via Social Login so I ended up going the on-demand Consume client instead.

Please let me know how the above sounds and if you need me to provide any more info or if the approach I'm taking is wrong in any way, any help is very much appreciated.

Cheers, Alby

engram-design commented 1 year ago

So if you just want to use authenticated API requests, you shouldn’t need to use Consume to do this. See https://verbb.io/craft-plugins/social-login/docs/feature-tour/requests

But if you prefer, sure using Consume will do largely the same thing. I’ll double check getToken() but that should return the value of the bearer token that’s recorded when he user authenticates themselves. You’d use this as you are doing for additional api requests.

ax2000 commented 1 year ago

Thanks for pointing me to the Requests feature that I completely missed. That looks that it will do exactly what I need without needing to use Consume.

I'll be testing this shortly and will let you know.

ax2000 commented 1 year ago

Thanks heaps for your help @engram-design. I'm running into a separate issue now but I want to debug it first and might open a separate ticket if persist.