pennersr / django-allauth

Integrated set of Django applications addressing authentication, registration, account management as well as 3rd party (social) account authentication.
https://allauth.org
MIT License
9.33k stars 3.01k forks source link

Amazon Cognito - Where to define my CustomAmazonCognitoProvider #3603

Closed b3nsh4 closed 7 months ago

b3nsh4 commented 7 months ago

Hi all, thanks for this wonderful package. I have a small question. I've completed setting up AWS Cognito account sign-in. Now, I need a small thing as well. It is to get custom user attributes from Cognito.

Question in short

Where can i add my CustomAmazonCognitoProvider after extending?

Brief overview

In allauth/socialaccount/providers/amazon_cognito/provider.py , we see the class AmazonCognitoProvider. Inside this class, there is extract_extra_data method. This method is responsible for getting attributes and it does the job well. Now, i want a custom attribute say; foo from Cognito. I've monkey patched the method - inside return just added "zoneinfo": data.get("custom:foo"). It does work as well.

What i've tried

Now that i know it can get the info, since its always better to extend the class, i did below;

from allauth.socialaccount.providers.amazon_cognito.provider import (
    AmazonCognitoProvider as BaseAmazonCognitoProvider,
)

class CustomAmazonCognitoProvider(BaseAmazonCognitoProvider):
    def extract_extra_data(self, data):
        extra_data = super(CustomAmazonCognitoProvider, self).extract_extra_data(data)
        # Add your custom field extraction logic here
        custom_field = data.get("custom:foo")
        extra_data["foo"] = custom_field
        print(f">>>>>>>>> hung:{extra_data}")
        return extra_data

I've added this CustomAmazonCognitoProvider in settings as:

SOCIALACCOUNT_PROVIDERS = {
    "amazon_cognito": {
        # "SOCIALACCOUNT_ADAPTER": "myapp.views.CustomAmazonCognitoProvider",
        "DOMAIN": "https://cogauth.auth.ap-south-1.amazoncognito.com",
        "APP": {"class": "polls.views.CustomAmazonCognitoProvider"},
    },
}

This caused raise MultipleObjectsReturned django.core.exceptions.MultipleObjectsReturned

Question

What i posted above, it might be also wrong, not sure where to put my CustomAmazonCognitoProvider. Question is, where do i put CustomAmazonCognitoProvider? Does CustomAmazonCognitoProvider seems to be okay?

Thanks for reading!

pennersr commented 7 months ago

This is possible, though the process is not documented as this mechanism is likely subject to change. Should that happen it will be noted in the changeog, so feel free to use it as is.

You can do the following: create your own module example.provider, containing:

from allauth.socialaccount.providers.amazon_cognito.provider import AmazonCognitoProvider

class CustomAmazonCognitoProvider(AmazonCognitoProvider):
    package = "allauth.socialaccount.providers.amazon_cognito"

    def extract_extra_data(self, data):
        ...

Then, in your settings.py:

    "amazon_cognito": {
        "APP": {
            "client_id": "...",
            "secret": "...",
        },
        "provider_class": "example.provider.CustomAmazonCognitoProvider",
b3nsh4 commented 7 months ago

This is possible, though the process is not documented as this mechanism is likely subject to change. Should that happen it will be noted in the changeog, so feel free to use it as is.

You can do the following: create your own module example.provider, containing:

from allauth.socialaccount.providers.amazon_cognito.provider import AmazonCognitoProvider

class CustomAmazonCognitoProvider(AmazonCognitoProvider):
    package = "allauth.socialaccount.providers.amazon_cognito"

    def extract_extra_data(self, data):
        ...

Then, in your settings.py:

    "amazon_cognito": {
        "APP": {
            "client_id": "...",
            "secret": "...",
        },
        "provider_class": "example.provider.CustomAmazonCognitoProvider",

Thanks, it works as expected!

b3nsh4 commented 4 months ago

@pennersr I've switched to Auth0 now. I'm able to login and looks good. But for logged in members, their email attribute is not returned (see below screenshot)

image

If my understanding is correct, https://github.com/pennersr/django-allauth/blob/105aace58fe767595c61e3a43563af7e1c277797/allauth/socialaccount/providers/auth0/provider.py#L15 this class retrieves the 'email' already? If so, what I'm i missing? I use a custom User model.

Thanks