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('/')