4

The docs for python-social auth describe how to add an authentication backend, but the don't say where to put the CLIENT_ID and CLIENT_SECRET of the new backed.

Here are the docs in question: http://python-social-auth.readthedocs.io/en/latest/backends/implementation.html#oauth

Zags
  • 37,389
  • 14
  • 105
  • 140

2 Answers2

2

I have implemented it this way:

from django.conf import settings

class CustomOAuth2(BaseOAuth2):
    name = 'custom'

    def get_key_and_secret(self):
        return settings.CUSTOM_OAUTH_CLIENT_ID, settings.CUSTOM_OAUTH_CLIENT_SECRET
Andrey Ovcharov
  • 299
  • 2
  • 12
  • While this works, it's not the best approach. Python-socail-auth has support for Django settings, and these are auto-generated for any custom backend. See https://stackoverflow.com/a/65891608/2800876 for how to set them – Zags Jan 25 '21 at 21:42
2

You specify them as django settings. The name of the settings are dynamically generated based on the name parameter of your custom backend, and are of the format SOCAIL_AUTH_[BACKEND_NAME]_KEY and SOCAIL_AUTH_[BACKEND_NAME]_SECRET.

So, for example, if your custom backend looks like this:

class TimelyOAuth2(BaseOAuth2):
    name = "custom-backend"
    # ...

You would put the following in settings.py:

SOCIAL_AUTH_CUSTOM_BACKEND_KEY = "..."
SOCIAL_AUTH_CUSTOM_BACKEND_SECRET = "..."

(Of course, don't put your key and secret directly in settings; use something like Django-environ)


Source

This is not documented anywhere in python-social-auth that I can find. I found this by reading the relevant bits of code in social_core/backends/base.py, social_core/strategy.py, and social_core/utils.py. The key method is get_key_and_secret which attempts to source these from settings variables. Relevant code excerpts are below:

# social_core/backends/base.py
class BaseAuth(object):
    def get_key_and_secret(self):
         return self.setting('KEY'), self.setting('SECRET')


# social_core/strategy.py
class BaseStrategy(object):
    def setting(self, name, default=None, backend=None):
        names = [setting_name(name), name]
        if backend:
            names.insert(0, setting_name(backend.name, name))
        for name in names:
            try:
                return self.get_setting(name)
            except (AttributeError, KeyError):
                pass
        return default


# social_core/utils.py
SETTING_PREFIX = 'SOCIAL_AUTH'

def to_setting_name(*names):
    return '_'.join([name.upper().replace('-', '_') for name in names if name])

def setting_name(*names):
    return to_setting_name(*((SETTING_PREFIX,) + names))
Zags
  • 37,389
  • 14
  • 105
  • 140