dj-rest-auth icon indicating copy to clipboard operation
dj-rest-auth copied to clipboard

Failed to exchange code for access token

Open wallinsonrocha opened this issue 2 years ago • 20 comments
trafficstars

Please, healp. I'm using google Auth2

{ "non_field_errors": [ "Failed to exchange code for access token" ] }

wallinsonrocha avatar Jun 30 '23 14:06 wallinsonrocha

I get the same problem for github

mdimranh avatar Jul 24 '23 02:07 mdimranh

I am experiencing the same issue for Google OAuth.

benfir123 avatar Aug 01 '23 07:08 benfir123

Same issue with Google. I tracked it down to this line in allauth, the response is {'error': 'invalid_grant', 'error_description': 'Bad Request'}. The feared invalid_grant message that can mean anything. Still trying to guess what is the problem in my case.

Strangely, I do can login using allauth directly.

andresmrm avatar Aug 02 '23 16:08 andresmrm

In my case I was getting invalid_grant because was reusing the code to debug. Using a new code gave me {'error': 'redirect_uri_mismatch', 'error_description': 'Bad Request'} on the first try. And that one was because the CALLBACK_URL_YOU_SET_ON_GOOGLE I used here https://accounts.google.com/o/oauth2/v2/auth?redirect_uri=<CALLBACK_URL_YOU_SET_ON_GOOGLE>&prompt=consent&response_type=code&client_id=<YOUR CLIENT ID>&scope=openid%20email%20profile&access_type=offline wasn't the same I used here:

class GoogleLogin(SocialLoginView): # if you want to use Authorization Code Grant, use this
    adapter_class = GoogleOAuth2Adapter
    callback_url = CALLBACK_URL_YOU_SET_ON_GOOGLE
    client_class = OAuth2Client

Source

andresmrm avatar Aug 02 '23 17:08 andresmrm

same issue here for last 2 weeks

panda1909 avatar Aug 03 '23 08:08 panda1909

You can also get the response message with a print after this line, like this:

            try:
                token = client.get_access_token(code)
            except OAuth2Error as ex:
                print(ex)  # <--
                raise serializers.ValidationError(
                    _('Failed to exchange code for access token')
                ) from ex

(You can go directly into your virtualenv files and edit it there to debug)

I'd suggest dj-rest-auth display the exception message somehow to simplify debugging.

andresmrm avatar Aug 03 '23 10:08 andresmrm

Hello, I hope this will still be relevant. I changed my callback uri to be postmessage

class GoogleLogin(
    SocialLoginView
):  # if you want to use Authorization Code Grant, use this
    adapter_class = GoogleOAuth2Adapter
    callback_url = "postmessage"
    client_class = OAuth2Client

This is in reference to this stack overflow question and answer: https://stackoverflow.com/a/48121098

nguthiru avatar Aug 12 '23 12:08 nguthiru

same issue here. Was that fixed ?

mirodil1 avatar Sep 30 '23 11:09 mirodil1

@andresmrm What was the actual error when you print(ex) ?

mirodil1 avatar Sep 30 '23 12:09 mirodil1

Sorry, I can't remember. But it was a much clearer message than invalid_grant.

andresmrm avatar Sep 30 '23 14:09 andresmrm

Needed to decode the auth code before exchanging it for the access tokens. google returns the auth code as url-encoded. In my case it was '/' -> '%2F'. answered here

mirodil1 avatar Oct 03 '23 12:10 mirodil1

Is this issue resolved? I'm still facing this problem not only with Google, but also with Facebook and Microsoft. Here's the error message, I'm getting:

{
    "non_field_errors": [
        "Failed to exchange code for access token"
    ]
}
class GoogleLogin(SocialLoginView):
   """
   Google Login
   """
   adapter_class = GoogleOAuth2Adapter
   callback_url = reverse_lazy('auth:social_google_login')
   client_class = OAuth2Client

class MicrosoftLogin(SocialLoginView):
   """
   Microsoft Login
   """
   adapter_class = MicrosoftGraphOAuth2Adapter
   client_class = OAuth2Client
   callback_url = reverse_lazy('auth:social_microsoft_login')
   
class FacebookLogin(SocialLoginView):
   """
   Facebook Login
   """
   adapter_class = FacebookOAuth2Adapter
   client_class = OAuth2Client
   callback_url = reverse_lazy('auth:social_facebook_login')

I'm using -

Django==4.2.5
django-allauth==0.55.2
dj-rest-auth==5.0.1

biblionest avatar Oct 13 '23 07:10 biblionest

@mirodil1

Needed to decode the auth code before exchanging it for the access tokens. google returns the auth code as url-encoded. In my case it was '/' -> '%2F'. answered here

Any chance you could show me exactly what this "decode the auth code" in code means actually?

When I make a login attempt via my angular application, I get a payload like this back from Google

{
    "idToken": "eyJhbGcixxxxxxx",
    "id": "1xxx",
    "name": "Name",
    "email": "[email protected]",
    "photoUrl": "https://lh3.googleusercontent.com/a/ACg8xxx",
    "firstName": "Name",
    "lastName": "Name",
    "provider": "GOOGLE"
}

So, I send to backend to the GoogleLogin(SocialLoginView):

At which point in this communication do I need to "decode" the auth code? How should the final decoded auth code look like?

I've been jumping around and everyone keeps saying what should be done, but nobody SHOWS the what should be done

😢

seanmavley avatar Nov 23 '23 16:11 seanmavley

For me it was to match the redirect_uri that was going to google

redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Faccounts%2Flogin%2F

with the one expected by django backend


class GoogleLogin(SocialLoginView):

    """
    The frontend will make a POST request to this endpoint with the code
    retrieved from Google to log the user in.

    Returns inner django JWT access and refresh token with other data

    ref- https://dj-rest-auth.readthedocs.io/en/latest/installation.html#social-authentication-optional

    """

    client_class = OAuth2Client
    callback_url = "http://localhost:3000/accounts/login/"

    # callback_url = os.getenv("GOOGLE_OAUTH_CALLBACK_URL")
    adapter_class = GoogleOAuth2Adapter

baditaflorin avatar Nov 27 '23 17:11 baditaflorin

For myself the issue was that I was getting an implicit code from Google and sending that to a df-rest-auth endpoint configured for the Authorization Code Grant workflow.

After adjusting the endpoint as per https://github.com/iMerica/dj-rest-auth/issues/525#issuecomment-1675885190, and using flow: "auth-code" in react-oauth, I can log in and sign up users through the GoogleLogin endpoint

raphaelmerx avatar Jan 08 '24 08:01 raphaelmerx

Hello, I hope this will still be relevant. I changed my callback uri to be postmessage

class GoogleLogin(
    SocialLoginView
):  # if you want to use Authorization Code Grant, use this
    adapter_class = GoogleOAuth2Adapter
    callback_url = "postmessage"
    client_class = OAuth2Client

This is in reference to this stack overflow question and answer: https://stackoverflow.com/a/48121098

this fixed my issue. it should be mentioned in the docs.

geekynasir avatar Jan 25 '24 14:01 geekynasir

At least, please update the documentation. Spent hours trying to debug this and went nearly crazy comparing the redirect_uris.

philippwiesner avatar Aug 03 '24 22:08 philippwiesner