pythondjangogoogle-oauthdjango-allauthdjango-oauth

Manage django-allauth social applications from admin portal


In all the tutorials I've seen, the django-allauth settings are all in the settings.py file. However, this ends up being kind of messy:

SOCIALACCOUNT_PROVIDERS = {
    "google": {
        "SCOPE": [
            "profile",
            "email",
        ],
        "AUTH_PARAMS": {
            "access_type": "online",
            "redirect_uri": "https://www.********.com/accounts/google/login/callback/",
        },
        "OAUTH_PKCE_ENABLED": True,
    }
}

SITE_ID = 1
SOCIALACCOUNT_ONLY = True
ACCOUNT_EMAIL_VERIFICATION = 'none'
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_AUTHENTICATION_METHOD = 'email'
LOGIN_REDIRECT_URL = 'https://www.********.com/success/'
ROOT_URLCONF = 'gvautoreply.urls'

So my question is, how can I fully manage Social Applications and their settings from the admin portal? I see that there is a settings field that takes JSON input, but I can't find any documentation on how to use it.


Solution

  • Yes. You can freely manage this from the database, or from settings, here's the documentation for your question. As far as I understand, it used to be possible to set provider settings exclusively using the database, but that has changed in this version. Here's a quote from first document:

    Even though providers with other protocols may use different terminology, the overall idea remains the same. Throughout allauth the term “social app” (“app” for short) refers to the unit of configuration of a provider. You provide the app configuration either in your project settings.py, or, by means of setting up SocialApp instances via the Django admin.

    Important: While you can mix both methods, be aware you need to avoid configuring one and the same provider both via settings.py and a SocialApp instance. In that case, it is not clear what app to pick, resulting in a MultipleObjectsReturned exception.

    For example, it will produce similar results:

    # settings.py
    
    SOCIALACCOUNT_PROVIDERS = {  
        'google': {  
            'APP': {  
                'client_id': '123',  
                'secret': '456',  
                'key': '789',  
                'settings': {  
                    'scope': [  
                        'profile',  
                        'email',  
                    ],  
                    'auth_params': {  
                        'access_type': 'online',  
                    },  
                    'oauth_pkce_enabled': True,  
                },  
            }  
        },  
    }
    

    Admin Interface: admin

    But in this way not all settings can be managed, but only those provider settings that are necessary to perform authentication. For example, there are some settings that are extracted from SOCIALACCOUNT_PROVIDERS['google'], and they cannot be set from the database. They are set as constants in the google provider dictionary at the top level:

    SOCIALACCOUNT_PROVIDERS = {
        'google': {
            'FETCH_USERINFO': True,
        },
    }
    

    Or the example you gave in the question:

    SOCIALACCOUNT_PROVIDERS = {
        "google": {
            "SCOPE": [
                "profile",
                "email",
            ],
            "AUTH_PARAMS": {
                "access_type": "online",
                "redirect_uri": "https://www.********.com/accounts/google/login/callback/",
            },
            "OAUTH_PKCE_ENABLED": True,
        }
    }
    

    These are essentially general settings and have the lowest priority, for example if in the database or in SOCIALACCOUNT_PROVIDERS['google']['APP'] you have not specified settings for SCOPE these will be used. For example, you can see this here, in the methods: get_pkce_params, get_auth_params, get_scope.

    In general, this whole code is quite a tangle, and you should try hard to unravel it. But if you are interested, here is a chain of how it works:

    1. Here create google controllers and install GoogleOAuth2Adapter as an adapter.
    2. Then, for example, when processing google-callback here self.adapter.get_provider(), this method OAuth2Adapter.get_provider will be called with these arguments: get_adapter(self.request).get_provider(self.request,provider='google').
    3. If you haven't changed anything in the settings ADAPTER this will return DefaultSocialAccountAdapter and just here you can see how the settings are searched. Initially the get_provider method will be called, which will call ⇾ get_applist_apps in the chain. Actually we are interested in the last method, this is where the most interesting thing happens. First the database is checked, then google['APPS'] or google['APP'] if APPS is not set, eventually a list of instances of the SocialApp model will be returned.

    I hope I didn't miss anything, let me know if there is something you didn't understand, I will try, to complete the answer.