Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sign In with Apple KeyError: 'id_token' #201

Closed
gabe-lucas opened this issue Dec 23, 2020 · 10 comments
Closed

Sign In with Apple KeyError: 'id_token' #201

gabe-lucas opened this issue Dec 23, 2020 · 10 comments

Comments

@gabe-lucas
Copy link

gabe-lucas commented Dec 23, 2020

I want to start off by saying fantastic job on this package.

An issue was raised on StackOverflow last week about Sign In with Apple and rest-auth here that is not seeing much traffic.
This issue seems to be the same with dj-rest-framework.

Following the example, this is what I got:

from allauth.socialaccount.providers.apple.views import AppleOAuth2Adapter
from allauth.socialaccount.providers.apple.client import AppleOAuth2Client
from dj_rest_auth.registration.views import SocialLoginView

class AppleLogin(SocialLoginView):
    """
    Class used for Sign In with Apple authentication.
    """
    adapter_class = AppleOAuth2Adapter
    client_class = AppleOAuth2Client
    callback_url = 'example.com'

Submitting the access_token and code, you get the same KeyError: 'id_token' (targeting the same line) that is mentioned in the Stack Overflow question.

When using Django allauth exclusively, Sign In with Apple works. It's only over the API requests that it does not.

Thanks for the help.

@fialkovod
Copy link

You have to submit CODE only, not access_token (and not access_token AND code).

@gabe-lucas
Copy link
Author

@fialkovod Thanks for your help on this.

When I submit only the code parameter, I get a 500 error.

OAuth2Error at /api/v2/dj-rest-auth/apple/
Error retrieving access token: b'{"error":"invalid_grant"}'

Do you believe that this is an error with the swift code that I am using to submit it? I had found this online and seems to be what people have luck with. It takes the authorizationCode from the response and sends it to dj-rest-auth as code.

I really appreciate it!

@iMerica
Copy link
Owner

iMerica commented Dec 31, 2020

It sounds like this is a client error so I'm going to close this. Let me know if I'm mistaken.

@iMerica iMerica closed this as completed Dec 31, 2020
@gabe-lucas
Copy link
Author

It sounds like this is a client error so I'm going to close this. Let me know if I'm mistaken.

After a few day's of looking into this, it's actually an issue with the SocialLoginSerializer from dj-rest-auth.

Here is the custom serializer, changes and steps that needed to be used.

What are your thoughts on adding a serializer to dj-rest-auth exclusively for Apple's version of OAuth? I can help with a PR if this is a route to consider.

Edit: The linked Stack Overflow question was also updated with the same information today.

@iMerica
Copy link
Owner

iMerica commented Jan 4, 2021

Sounds good. I'll re-open this ticket now.

@iMerica iMerica reopened this Jan 4, 2021
@LanceMoe
Copy link
Contributor

LanceMoe commented Jan 8, 2021

In our project, I used access_token and id_token to support Apple login. #205 is my solution.
I read the code of allauth, and I found that the client and adapter part of Sign in with Apple is very different from the others.
In AppleOAuth2Adapter, the code subclass the OAuth2Adapter and override the get_access_token_data:

    def get_access_token_data(self, request, app, client):
        """ We need to gather the info from the apple specific login """
        add_apple_session(request)

        # Exchange `code`
        code = get_request_param(request, "code")
        access_token_data = client.get_access_token(code)

        return {
            **access_token_data,
            **self.get_user_scope_data(request),
            "id_token": request.apple_login_session.get("id_token"),
        }

You can see, before getting access_token_data = client.get_access_token(code), the adapter method called add_apple_session, and here is the add_apple_session:

def add_apple_session(request):
    """
    Fetch an apple login session
    """
    if not hasattr(request, "apple_login_session"):
        session_key = request.COOKIES.get(APPLE_SESSION_COOKIE_NAME)
        request.apple_login_session = SessionStore(session_key)

It can be seen that if we use the RESTful API, we may not bring the session_key.
So I think the correct way is to directly use the combination of access_token and id_token to Sign in with Apple. And it works for my project. (Just use the authorizationCode as access_token, and identityToken as id_token, it worked.)
With this pull request, you need just add the view as the following:

class AppleLoginView(SocialLoginView):
    adapter_class = AppleOAuth2Adapter
    callback_url = 'https://yourdomain/accounts/apple/login/callback/'
    client_class = AppleOAuth2Client


class AppleConnectView(SocialConnectView):
    adapter_class = AppleOAuth2Adapter
    callback_url = 'https://yourdomain/accounts/apple/login/callback/'
    client_class = AppleOAuth2Client

apple_login_view = AppleLoginView.as_view()
apple_connect_view = AppleConnectView.as_view()

Hope it can be helpful.

@gabe-lucas
Copy link
Author

@LanceMoe I think your solution is much easier and more effective than the one listed in allauth (that I followed and posted about). I tested your PR and it works really well and keeps it to the one serializer. Thank you for doing that.

@iMerica
Copy link
Owner

iMerica commented Jan 11, 2021

Closing this as the PR has been merged.

@iMerica iMerica closed this as completed Jan 11, 2021
@aehlke
Copy link

aehlke commented May 10, 2021

I recommend documenting this support. It took a while to find this superior looking solution after stumbling with django-allauth

@Tikam02
Copy link

Tikam02 commented Jan 5, 2022

It sounds like this is a client error so I'm going to close this. Let me know if I'm mistaken.

After a few day's of looking into this, it's actually an issue with the SocialLoginSerializer from dj-rest-auth.

Here is the custom serializer, changes and steps that needed to be used.

What are your thoughts on adding a serializer to dj-rest-auth exclusively for Apple's version of OAuth? I can help with a PR if this is a route to consider.

Edit: The linked Stack Overflow question was also updated with the same information today.

can you send the StackOverflow link.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants