Django Easy way: python-social-auth


Example

python-social-auth is a framework that simplifies the social authentication and authorization mechanism. It contains many social backends (Facebook, Twitter, Github, LinkedIn, etc.)

INSTALL

First we need to install the python-social-auth package with

pip install python-social-auth

or download the code from github. Now is a good time to add this to your requirements.txt file.

CONFIGURING settings.py

In the settings.py add:

INSTALLED_APPS = (
    ...
    'social.apps.django_app.default',
    ...
)

CONFIGURING BACKENDS

AUTHENTICATION_BACKENDS contains the backends that we will use, and we only have to put what's we need.

AUTHENTICATION_BACKENDS = (
    'social.backends.open_id.OpenIdAuth',
    'social.backends.google.GoogleOpenId',
    'social.backends.google.GoogleOAuth2',
    'social.backends.google.GoogleOAuth',
    'social.backends.twitter.TwitterOAuth',
    'social.backends.yahoo.YahooOpenId',
    ...
    'django.contrib.auth.backends.ModelBackend',
)

Your project settings.py may not yet have an AUTHENTICATION_BACKENDS field. If that is the case add the field. Be sure not to miss 'django.contrib.auth.backends.ModelBackend', as it handles login by username/password.

If we use for example Facebook and Linkedin Backends we need to add the API keys

SOCIAL_AUTH_FACEBOOK_KEY = 'YOURFACEBOOKKEY'
SOCIAL_AUTH_FACEBOOK_SECRET = 'YOURFACEBOOKSECRET'

and

SOCIAL_AUTH_LINKEDIN_KEY = 'YOURLINKEDINKEY'
SOCIAL_AUTH_LINKEDIN_SECRET = 'YOURLINKEDINSECRET'

Note: You can Obtain the nedded keys in Facebook developers and Linkedin developers and here you can see the full list and his respective way to especify the API key and the key Secret.

Note on Secret Keys: Secret keys should be kept secret. Here is a Stack Overflow explanation that is helpful. This tutorial is helpful for learning about enviromental variables.

TEMPLATE_CONTEXT_PROCESSORS will help to redirections, backends and other things, but at beginning we only need these:

TEMPLATE_CONTEXT_PROCESSORS = (
    ...
    'social.apps.django_app.context_processors.backends',
    'social.apps.django_app.context_processors.login_redirect',
    ...
)

In Django 1.8 setting up TEMPLATE_CONTEXT_PREPROCESSORS as shown above was deprecated. If this is the case for you you'll add it inside of the TEMPLATES dict. Yours should look something similar to this:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, "templates")],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'social.apps.django_app.context_processors.backends',
                'social.apps.django_app.context_processors.login_redirect',
            ],
        },
    },
] 

USING A CUSTOM USER

If you are using a custom User Model and want to asociate with it, just add the following line (still in settings.py)

SOCIAL_AUTH_USER_MODEL = 'somepackage.models.CustomUser'    

CustomUser is a model which inherit or Abstract from default User.

CONFIGURING urls.py

# if you haven't imported inlcude make sure you do so at the top of your file
from django.conf.urls import url, include

urlpatterns = patterns('',
    ...
    url('', include('social.apps.django_app.urls', namespace='social'))
    ...
)

Next need to sync database to create needed models:

./manage.py migrate

Finally we can play!

in some template you need to add something like this:

    <a href="{% url 'social:begin' 'facebook' %}?next={{ request.path }}">Login with Facebook</a>
    <a href="{% url 'social:begin' 'linkedin' %}?next={{ request.path }}">Login with Linkedin</a>

if you use another backend just change 'facebook' by the backend name.

Logging users out

Once you have logged users in you'll likely want to create the functionality to log them back out. In some template, likely near where the log in template was shown, add the following tag:

<a href="{% url 'logout' %}">Logout</a>

or

<a href="/logout">Logout</a>

You'll want to edit your urls.py file with code similar to:

url(r'^logout/$', views.logout, name='logout'),

Lastly edit your views.py file with code similar to:

def logout(request):
    auth_logout(request)
    return redirect('/')