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 ERROR: Failed to exchange code for access token #669

Open
LuisGMM opened this issue Nov 26, 2024 · 0 comments
Open

Sign in with Apple ERROR: Failed to exchange code for access token #669

LuisGMM opened this issue Nov 26, 2024 · 0 comments

Comments

@LuisGMM
Copy link

LuisGMM commented Nov 26, 2024

Apple's social login seems to fail somewhere.

I tried doing it manually with this to check my config:

import jwt
import time

# Replace these with your actual values
CLIENT_ID = 'XXXXX'
KEY_ID = 'XXXXX'
TEAM_ID = 'XXXXX'
PRIVATE_KEY = 'XXXXX'

def generate_client_secret():
    headers = {
        'kid': KEY_ID,
        'alg': 'ES256',
    }

    payload = {
        'iss': TEAM_ID,
        'iat': int(time.time()),  # Current time
        'exp': int(time.time()) + 3600,  # Expiration time (1 hour from now)
        'aud': 'https://appleid.apple.com',
        'sub': CLIENT_ID,  # Your app's Bundle ID
    }

    client_secret = jwt.encode(payload, PRIVATE_KEY, algorithm='ES256', headers=headers)

    return client_secret


if __name__ == '__main__':
    print(generate_client_secret())

Then using the code provided from the frontend (Flutter) to generate the access_token:

curl -X POST https://appleid.apple.com/auth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d 'client_id=XXXXX' \
-d 'client_secret=XXXXX' \
-d 'code=XXXXX' \
-d 'grant_type=authorization_code' \
-d 'redirect_uri=https://XXXXX'

Which returns:

{"access_token":"XXXXX","token_type":"Bearer","expires_in":3600,"refresh_token":"XXXXX","id_token":"XXXXX"}

I have these settings in django:

INSTALLED_APPS = [
    # For authentication
    'dj_rest_auth',
    # For registration and social login
    'django.contrib.sites',
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    'dj_rest_auth.registration',
    'allauth.socialaccount.providers.google',
    'allauth.socialaccount.providers.apple',
]

MIDDLEWARE = [
    #
    'allauth.account.middleware.AccountMiddleware',
    #
]

SOCIALACCOUNT_PROVIDERS = {
    'apple': {
        'APP': {
            'client_id': 'XXXXX',
            'key_id': 'XXXXX',
            'team_id': 'XXXXX',
            'secret': """-----BEGIN PRIVATE KEY-----
XXXXX
-----END PRIVATE KEY-----""",
        },
        'SCOPE': ['name', 'email'],
    }
}

And this view:

class AppleLogin(SocialLoginView):
    adapter_class = AppleOAuth2Adapter
    client_class = OAuth2Client
    callback_url = 'https://dev-api.ruit.es/api/v1/auth/accounts/apple/login/callback/'

    def post(self, request, *args, **kwargs):
        logging.api.log(logging.DEBUG, f'Incoming payload: {request.data}')

        logging.api.log(logging.DEBUG, f'Payload type: {type(request.data)} || Length of payload: {len(request.data)}')

        try:
            response = super().post(request, *args, **kwargs)
            logging.api.log(logging.DEBUG, f'Apple login response: {response.data}')

            return response
        except Exception as e:
            logging.api.log(logging.ERROR, f'Apple login failed: {e}')
            raise

I also tried using AppleOAuth2Client with these settings:

SOCIALACCOUNT_PROVIDERS = {
    'apple': {
        'APP': {
            'client_id': 'XXXXX',
            'team_id': 'XXXXX',
            'key': 'XXXXX',
            'settings': {
                'certificate_key': """-----BEGIN PRIVATE KEY-----
XXXXX
-----END PRIVATE KEY-----""",
            },
        },
        'SCOPE': ['name', 'email'],
    }
}

And the error is the same:

[2024-11-26 10:15:03] XXXXXXX.py:71 post DEBUG d6aa27db-1562-4923-bf4f-73407448a32b Incoming payload: {'code': 'c51a4cbfab4294aaf9dd3356311d5ebe6.0.syxz.h-aTBXlEwQmsRyUWZJJhLw', 'id_token': 'eyJraWQiOiJGZnRPTlR4b0VnIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwczovL2FwcGxlaWQuYXBwbGUuY29tIiwiYXVkIjoiZXMucnVpdC5ydWl0IiwiZXhwIjoxNzMyNzAyNTAyLCJpYXQiOjE3MzI2MTYxMDIsInN1YiI6IjAwMDg3OS40YzFiMDA2YjgxNmE0ZDU2ODJiNWUxOTg2OGMwYWI5Ny4wNzAwIiwiY19oYXNoIjoiYXVuc1JlMHVhUmdUM1Y2WjduUGVOdyIsImVtYWlsIjoiYnE3ZzhoYnloYkBwcml2YXRlcmVsYXkuYXBwbGVpZC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiaXNfcHJpdmF0ZV9lbWFpbCI6dHJ1ZSwiYXV0aF90aW1lIjoxNzMyNjE2MTAyLCJub25jZV9zdXBwb3J0ZWQiOnRydWV9.bycYP_SYAXEdKbTauGa7H6WxH6aaXFQrZR41y5yhexZjcIHZGOkDGDZhkLnPnmY4DErazj4yjgTzniKpPrq2a26jP1HJDauosdFvZr05GSoY-GycX1TWCUFrLNNBI8ef01xWs6_QEBpizQZg-4GAd0m9m924k3Zs2Kt_iGb54gWlcSEekjNpM8X_qrgniaD9IK5rgRuGXnS9RAgN6mUFVYenRZYPDBNXha691lp4IAHbWytmsPZpuwCwkuSrmVQW7T1UgoPZGoosSiAtwQwZG6jx700RmJoZaiCv2GMuFm2SPle4qqoWoePArL-Gtp6ml06hVTLzA5o384z9IPeZMQ'}
 [2024-11-26 10:15:03] XXXXXXX/views.py:73 post DEBUG d6aa27db-1562-4923-bf4f-73407448a32b Payload type: <class 'dict'> || Length of payload: 2
 [2024-11-26 10:15:04] XXXXXXX/.views.py:81 post ERROR d6aa27db-1562-4923-bf4f-73407448a32b Apple login failed: {'non_field_errors': [ErrorDetail(string='Failed to exchange code for access token', code='invalid')]}
 [2024-11-26 10:15:04] XXXXXXX.py:8 custom_exception_handler ERROR d6aa27db-1562-4923-bf4f-73407448a32b EXCEPTION: {'non_field_errors': [ErrorDetail(string='Failed to exchange code for access token', code='invalid')]} - Context: {'view': <core.views.AppleLogin object at 0x7f26e0bee410>, 'args': (), 'kwargs': {}, 'request': <rest_framework.request.Request: POST '/api/v1/auth/login/apple/'>}
 Traceback (most recent call last):
   File "/usr/local/lib/python3.11/site-packages/rest_framework/views.py", line 506, in dispatch
     response = handler(request, *args, **kwargs)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/ruit_back/core/views.py", line 76, in post
     response = super().post(request, *args, **kwargs)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/usr/local/lib/python3.11/site-packages/dj_rest_auth/views.py", line 125, in post
     self.serializer.is_valid(raise_exception=True)
   File "/usr/local/lib/python3.11/site-packages/rest_framework/serializers.py", line 231, in is_valid
     raise ValidationError(self.errors)
 rest_framework.exceptions.ValidationError: {'non_field_errors': [ErrorDetail(string='Failed to exchange code for access token', code='invalid')]}

I also tried with dj-rest-auth[with_social]==7.0.0 and dj-rest-auth[with_social]==6.0.0.

Is there some extra config

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

1 participant