iMerica / dj-rest-auth

Authentication for Django Rest Framework
https://dj-rest-auth.readthedocs.io/en/latest/index.html
MIT License
1.63k stars 304 forks source link

Failed to exchange code for access token #525

Open wallinsonrocha opened 1 year ago

wallinsonrocha commented 1 year ago

Please, healp. I'm using google Auth2

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

mdimranh commented 1 year ago

I get the same problem for github

benfir123 commented 12 months ago

I am experiencing the same issue for Google OAuth.

andresmrm commented 12 months ago

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 commented 12 months ago

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

panda1909 commented 12 months ago

same issue here for last 2 weeks

andresmrm commented 12 months ago

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.

nguthiru commented 11 months ago

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

mirodil1 commented 10 months ago

same issue here. Was that fixed ?

mirodil1 commented 10 months ago

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

andresmrm commented 10 months ago

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

mirodil1 commented 9 months ago

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

biblionest commented 9 months ago

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
seanmavley commented 8 months ago

@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@gmail.com",
    "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

😢

baditaflorin commented 8 months ago

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
raphaelmerx commented 6 months ago

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

nasir733 commented 6 months ago

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.