每次使用苹果登录时,Django 都会创建新用户

问题描述

通过查看此存储库的代码,我在 Django 上使用 Apple 后端实现了登录https://github.com/truffls/sign-in-with-apple-using-django/blob/master/backend.md

我对代码做了很少的改动,不会影响任何逻辑(比如更改声明名称等)

每次 iOS 应用使用苹果登录时,它都会奇怪地重新创建一个新用户

我有什么办法可以解决这个问题吗?

class AppleOAuth2(BaSEOAuth2):
    """
    Custom BaSEOAuth2 backend class for
    Sign in with Apple

    Usage:
    Add this to AUTHENTICATION_BACKENDS on settings.py
    """

    name             = 'apple'
    ACCESS_TOKEN_URL = 'https://appleid.apple.com/auth/token'
    ScopE_SEParaTOR  = ','
    ID_KEY           = 'uid'

    @handle_http_errors
    def do_auth(self,access_token,*args,**kwargs):
        """
        Finish the auth process once the access_token was retrieved
        Get the email from ID token received from apple

        do_auth override this method as you need to verify the code or access token given
        by mobile client from apple and get the ID token from which other details can be extracted.
        """

        ## Retrieve django project stored data
        client_id,client_secret = self.get_key_and_secret()

        headers = {'content-type': "application/x-www-form-urlencoded"}
        data = {
            'client_id'    : client_id,'client_secret': client_secret,'code'         : access_token,'grant_type'   : 'authorization_code','redirect_uri' : 'https://example-app.com/redirect'
        }



        ## Form data

        # ID Token(= from AppleID Service)
        res = requests.post(AppleOAuth2.ACCESS_TOKEN_URL,data = data,headers = headers)
        response_dict = res.json()
        id_token = response_dict.get('id_token',None)


        # Response Data
        response_data = {}

        if id_token:
            decoded = jwt.decode(id_token,'',verify = False)
            response_data.update({'email': decoded['email']}) if 'email' in decoded else None
            response_data.update({'uid': decoded['sub']}) if 'sub' in decoded else None

        # Response
        response = kwargs.get('response') or {}
        response.update(response_data)
        response.update({'access_token': access_token}) if 'access_token' not in response else None



        ## Authenticate
        kwargs.update({'response': response,'backend': self})
        return self.strategy.authenticate(*args,**kwargs)


    def get_user_details(self,response):
        """
        get_user_details override just to give the email address or other user
        information back to the Python Social Auth framework
        """
        email = response.get('email',None)
        details = {
            'email': email,}
        return details


    def get_key_and_secret(self):
        """
        get_key_and_secret override this as you have to generate
        the client secret the way mentioned above

        :return:
        - App Bundle ID
        - Client Secret
        """
        headers = {
            'kid': settings.soCIAL_AUTH_APPLE_KEY_ID
        }

        payload = {
            'iss': settings.soCIAL_AUTH_APPLE_TEAM_ID,'iat': timezone.Now(),'exp': timezone.Now() + timedelta(days = 180),'aud': 'https://appleid.apple.com','sub': settings.soCIAL_AUTH_APPLE_APP_BUNDLE_ID,}

        client_secret = jwt.encode(
            payload,settings.soCIAL_AUTH_APPLE_KEY_SECRET,algorithm = 'ES256',headers = headers
        ).decode("utf-8")

        return settings.soCIAL_AUTH_APPLE_APP_BUNDLE_ID,client_secret

我收到来自 Apple 的错误

{'error': 'invalid_grant','error_description': 'The code has expired or has been revoked.'}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)