django.core.exceptions.MultipleObjects在 Django-Allauth 中返回错误

问题描述 投票:0回答:1

我在尝试访问 Django-allauth 中的“kakao”提供程序时遇到问题。 (实际上,谷歌现在有一个版本问题,所以我想先弄清楚kakao)我有一个MultipleObjectsReturned或ObjectDoesNotExist的例外。我已按照文档进行操作并尝试了各种故障排除步骤,但问题仍然存在。

这是我的views.py 文件中的代码:

def kakao_callback(request):
    code = request.GET.get("code")
    print(f"code : {code}")
    
    # ---- Access Token Request ----
    token_req = requests.get(
        f"https://kauth.kakao.com/oauth/token?grant_type=authorization_code&client_id={KAKAO_REST_API_KEY}&redirect_uri={KAKAO_REDIRECT_URI}&code={code}"
    )
    token_req_json = token_req.json()
    error = token_req_json.get("error", None)
    if error is not None:
        raise JSONDecodeError(f"Failed to decode JSON: {error}", '{"error": "your_error_message"}', 0)

    access_token = token_req_json.get("access_token")
    print(f"access_token : {access_token}")
    
    # ---- Email Request ----
    profile_request = requests.post(
        "https://kapi.kakao.com/v2/user/me",
        headers={"Authorization": f"Bearer {access_token}"},
    )
    profile_json = profile_request.json()
    error = profile_json.get("error", None)
    if error is not None:
        raise JSONDecodeError("Failed to decode JSON", '{"error": "your_error_message"}', 0)

    kakao_account = profile_json.get("kakao_account")
    email = kakao_account.get("email", None)
    profile = kakao_account.get("profile")
    nickname = profile.get("nickname")
    profile_image = profile.get("thumbnail_image_url")
    # print(email)
    
    # ---- Signup or Signin Request ----
    try:
        user = User.objects.get(email=email)
        social_user = SocialAccount.objects.get(user=user)
        if social_user is None:
            return JsonResponse(
                {"err_msg": "email exists but not kakao social user"},
                status=status.HTTP_400_BAD_REQUEST,
            )
        if social_user.provider != "kakao":
            return JsonResponse(
                {"err_msg": "no matching social type"},
                status=status.HTTP_400_BAD_REQUEST,
            )
            

        data = {"access_token": access_token, "code": code}
        accept = requests.post(f"{BASE_URL}accounts/kakao/login/finish/", data=data)
        accept_status = accept.status_code
        
        if accept_status != 200:
            print(f"Accept request status code: {accept.status_code}")
            return JsonResponse({"err_msg": "failed to signin_registered user."}, status=accept_status)
        accept_json = accept.json()
        accept_json.pop('user', None)
        refresh_token = accept.headers['Set-Cookie']
        refresh_token = refresh_token.replace('=',';').replace(',',';').split(';')
        token_index = refresh_token.index(' refresh_token')
        cookie_max_age = 3600 * 24 * 14 # 14 days
        refresh_token = refresh_token[token_index+1]
        response_cookie = JsonResponse(accept_json)
        response_cookie.set_cookie('refresh_token', refresh_token, max_age=cookie_max_age, httponly=True, samesite='Lax')
        return response_cookie
    
    except User.DoesNotExist:
        cookie_max_age = 3600 * 24 * 14
        data = {"access_token": access_token, "code": code}
        accept = requests.post(f"{BASE_URL}accounts/kakao/login/finish/", data=data)
        accept_status = accept.status_code  
    
        if accept_status != 200:
            print(f"Failed to signup_new user. Status code: {accept_status}")
            return JsonResponse({"err_msg": "failed to signup_new user"}, status=accept_status)

        accept_json = accept.json()
        accept_json.pop('user', None)
        refresh_token = accept.headers['Set-Cookie']
        refresh_token = refresh_token.replace('=',';').replace(',',';').split(';')
        token_index = refresh_token.index(' refresh_token')
        refresh_token = refresh_token[token_index+1]

        response_cookie = JsonResponse(accept_json)
        response_cookie.set_cookie('refresh_token', refresh_token, max_age=cookie_max_age, httponly=True, samesite='Lax')
        return response_cookie
    
    except JSONDecodeError as e:
        print(f"JSONDecodeError: {e}")
        raise
    
    except User.MultipleObjectsReturned as e:
        print(f"MultipleObjectsReturned: {e}")
        return JsonResponse(
            {"err_msg": "MultipleObjectsReturned. Check logs for details."},
            status=status.HTTP_500_INTERNAL_SERVER_ERROR,
        )
    
    except:
        return JsonResponse({"MESSAGE":"KEY_ERROR"}, status=400)

我检查了数据库,SocialApp 表中有“kakao”和“google”提供商的两个条目。为此提供程序正确设置了 client_id。另外,当我检查

SocialApp.objects.all()
时,它出来了[<SocialApp: Kakao>, <SocialApp: google>]>。

这是 settings.py 文件中 SOCIALACCOUNT_PROVIDERS 的代码:

SOCIALACCOUNT_PROVIDERS = {
    'kakao': {
        'APP': {
            'client_id': KAKAO_SECRET_KEY,
            'secret': KAKAO_REST_API_KEY,
        }
    },
    'google': {
        'APP':{
            'clinet_id':secrets['SOCIAL_AUTH_GOOGLE_CLIENT_ID'],
            'secret': secrets['SOCIAL_AUTH_GOOGLE_SECRET']
            },
    }
}

跟踪日志:


File "C:\Users\user\anaconda3\envs\Pj\Lib\site-packages\allauth\socialaccount\adapter.py", line 290, in get_app
    raise MultipleObjectsReturned
django.core.exceptions.MultipleObjectsReturned
python django django-rest-framework django-allauth python-social-auth
1个回答
0
投票

您似乎可能设置了两个 kakao 帐户实例 - 一个在您的 settings.py 文件中,另一个在您的 Django 管理控制台中。

要解决此问题,请考虑根据您的要求删除其中一个。您可以删除 settings.py 文件中的配置或从 Django 管理控制台中删除该条目。

以下是如何删除 settings.py 中的配置并将其保留在管理控制台中的示例:

蟒蛇 复制代码

settings.py(你可以删除它并将其保留在管理员中)

SOCIALACCOUNT_PROVIDERS = {
    'kakao': {
        'APP': {
            'client_id': '123',
            'secret': '456',
            'key': ''
        }
    }
}

进行必要的更改后,不要忘记运行迁移来应用更改:

python manage.py makemigrations
python manage.py migrate

这应该有助于解决与 kakao 帐户配置的多个实例相关的问题。

© www.soinside.com 2019 - 2024. All rights reserved.