Social authentication is a powerful feature that allows users to log in to your Django web application using their social media accounts like Facebook, Google, Twitter, and more. It simplifies the registration and login process for users while providing additional user data for your application. In this tutorial, we’ll explore how to integrate social authentication in Django using the django-social-auth
library with practical examples.
Read our new blogs:
- Add Facebook Login to Django Website using django-allauth
- Add Google Gmail Login to Django Website using django-allauth
- Add Github Login to Django Website using django-allauth
Table of contents
Basic Setup
Step 1: Installation – First, install the django-social-auth
library using pip:
pip install social-auth-app-django
Step 2: Settings Configuration – Add 'social_django'
to your INSTALLED_APPS
in your project’s settings (settings.py
):
# settings.py
INSTALLED_APPS = [
# ...
'social_django',
# ...
]
Step 3: Migrations
python manage.py makemigrations
python manage.py migrate
The library will automatically handle auth tokens and all the required information to deal with OAuth and OAuth2. Generally speaking, you won’t need to handle it manually nor access the user’s social profile.
Step 4: Configuration of Django Social Auth App – Update the MIDDLEWARE_CLASSES
by adding the SocialAuthExceptionMiddleware
to the end of it:
MIDDLEWARE_CLASSES = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'social_django.middleware.SocialAuthExceptionMiddleware', # <-- Here
]
Now we update the context_processors
inside TEMPLATE
:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [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_django.context_processors.backends', # <-- Here
'social_django.context_processors.login_redirect', # <-- Here
],
},
},
]
Add the AUTHENTICATION_BACKENDS
in your settings.py
file:
AUTHENTICATION_BACKENDS = (
'social_core.backends.facebook.FacebookOAuth2',
'social_core.backends.twitter.TwitterOAuth',
'social_core.backends.github.GithubOAuth2',
'django.contrib.auth.backends.ModelBackend',
)
So, here, we will need to specify the correct backends, depending on your needs. Since here in this example, we will be working with Facebook, Twitter, and GitHub, so I have just added those three backends if you see above in AUTHENTICATION_BACKENDS
.
Note: Use this link to add How to add Login Logout in Django Project. This link will also help you to show where to keep your Django templates.
Step 5: Update the urls.py
add the social-auth-app-django
URLs:
from django.contrib import admin
from django.urls import path, include
from core import views as core_views
from django.contrib.auth import views as auth_views
urlpatterns = [
path('admin/', admin.site.urls),
path('', core_views.HomeView.as_view(), name='home'),
# Login and Logout
path('login/', auth_views.LoginView.as_view(), name='login'),
path('logout/', auth_views.LogoutView.as_view(next_page='home'), name='logout'),
path('oauth/', include('social_django.urls', namespace='social')), # <-- here
]
Now set the default values for the LOGIN_URL
, LOGOUT_URL
and the LOGIN_REDIRECT_URL
in settings.py. The LOGIN_REDIRECT_URL
is used to redirect the user after authenticating from Django Login and Social Auth.
LOGIN_URL = 'login'
LOGOUT_URL = 'logout'
LOGIN_REDIRECT_URL = 'home'
As we are using the built-in login
and logout
views, let’s just create the home
view inside the core app:
views.py
from django.shortcuts import render
from django.views.generic import TemplateView
from django.contrib.auth.mixins import LoginRequiredMixin
class HomeView(LoginRequiredMixin, TemplateView):
template_name = "home.html"
home.html
{% extends 'base.html' %}
{% block content %}
<h2>My Social Login Homepage</h2>
<p>Hi {{ user.username }}!</p>
{% endblock %}
We are good to go. For each and every social network, you need to register your app in their system. So from now onwards the steps will vary on the auth service provider. Let’s tackle them one at a time.
Facebook Login Integration in Django Webiste
Go to developers.facebook.com/ click on My Apps and then Create App (If new click on Get Started and create your developer account). Fill in the app name and contact email and click on Create App ID.
From the sidebar, go to Settings -> Basic, grab the App ID and App Secret (click on the Show button to get it as plain text):
SOCIAL_AUTH_FACEBOOK_KEY = 'APP_ID'
SOCIAL_AUTH_FACEBOOK_SECRET = 'APP_SECRET'
Change above App ID and App Secret and add it to settings.py file
Now go to Settings -> Basic at bottom. First click on the button + Add Platform and add a website. For the Site URL put http://localhost:8000 and then in the App Domains put just localhost, like the picture below:
Note: For Facebook, we can’t use 127.0.0.1 as the callback. Instead, use the localhost.
Save changes and we are good to go. Now update the registration/login.html file with the Facebook link:
{% extends 'base.html' %}
{% block title %}Login Page{% endblock title %}
{% block content %}
<h2>Login</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Login</button>
</form>
<br>
<p><strong>-- OR --</strong></p>
<a href="{% url 'social:begin' 'facebook' %}">Login with Facebook</a>
{% endblock content %}
Let’s try it now. Click on login with Facebook
You will be redirected to facebook to grant access, click on continue. And there you go!!!!
Django Twitter Login
Go to apps.twitter.com and click on Create an App. (If you have not created a developer account it will ask for detail just fill it.)
Add the details just like you did with the Facebook App:
For Twitter, we will use the http://localhost:8000/oauth/complete/twitter/ callback url.
Go to Permissions tab and change the permissions to Read Only:
Now go to Keys and Access Tokens tab and grab the API Key and API Secret and update the settings.py:
SOCIAL_AUTH_TWITTER_KEY = 'AUTH_KEY'
SOCIAL_AUTH_TWITTER_SECRET = 'SECRET_KEY'
Change above App ID and App Secret and add it to settings.py file
To enable the Twitter Login, simple update the registeration/login.html template:
{% extends 'base.html' %}
{% block title %}Login Page{% endblock title %}
{% block content %}
<h2>Login</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Login</button>
</form>
<br>
<hr/>
<p><strong>-- OR --</strong></p>
<a href="{% url 'social:begin' 'twitter' %}">Login with Twitter</a>
{% endblock content %}
Let’s try it now. Click on login with Twitter.
You will be redirected to Twitter to grant access, click on continue. And there you go!!!!
Django GitHub Login
Log in to your GitHub account, go to Settings. In the left menu, you will see Developer settings. Click on OAuth apps.
In the OAuth applications screen click on Register a new application. Or simply click on the link – https://github.com/settings/applications/new
Provide the information below:
The most important step is the Authorization callback URL. I’m putting a localhost URL. http://localhost:8000/oauth/complete/github/.
After you create the app, you will be redirected to this screen:
Now we update the settings.py with the client ID and client Secret:
SOCIAL_AUTH_GITHUB_KEY = 'AUTH_GITHUB_KEY'
SOCIAL_AUTH_GITHUB_SECRET = 'AUTH_GITHUB_SECRET'
Login View
Let’s create a Login View that can handle the GitHub Login. The default login view look for a template in registration/login.html. Let’s create it:
registration/login.html
{% extends 'base.html' %}
{% block title %}Login Page{% endblock title %}
{% block content %}
<h2>Login</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Login</button>
</form>
<br>
<hr/>
<p><strong>-- OR --</strong></p>
<a href="{% url 'social:begin' 'github' %}">Login with Github</a> <br/>
{% endblock content %}
Note that the important part to start the GitHub authentication is {% url 'social:begin' 'github' %}
.
Now, the login page should look like this:
After clicking on Login with GitHub it will redirect to Authorization link, click on Authorize Application. And you are good to go.
Social Auth Management Page
Now, let’s add a Settings page in our application, where the user can manage the social auth logins. It’s a good way for the user to authorize new services or revoke access.
Basically this page will be responsible for:
- Provide means to connect to other social networks
- Disconnecting the user from the social networks
- Control if the user can disconnect (that is, the user have defined a password, so he/she won’t be locked out of the system)
urls.py
urlpatterns = [
# ...
path('settings/', core_views.SettingsView.as_views(), name='settings'),
path('settings/password/', core_views.password, name='password'),
]
A password view will be very important in this case!
Now update the project settings.py file with the following configurations:
settings.py
SOCIAL_AUTH_LOGIN_ERROR_URL = '/settings/'
SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/settings/'
SOCIAL_AUTH_RAISE_EXCEPTIONS = False
views.py
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import AdminPasswordChangeForm, PasswordChangeForm
from django.contrib.auth import update_session_auth_hash
from django.contrib import messages
from django.shortcuts import render, redirect
from social_django.models import UserSocialAuth
class SettingsView(LoginRequiredMixin, TemplateView):
def get(self, request, *args, **kwargs):
user = request.user
try:
github_login = user.social_auth.get(provider='github')
except UserSocialAuth.DoesNotExist:
github_login = None
try:
twitter_login = user.social_auth.get(provider='twitter')
except UserSocialAuth.DoesNotExist:
twitter_login = None
try:
facebook_login = user.social_auth.get(provider='facebook')
except UserSocialAuth.DoesNotExist:
facebook_login = None
can_disconnect = (user.social_auth.count() > 1 or user.has_usable_password())
return render(request, 'core/settings.html', {
'github_login': github_login,
'twitter_login': twitter_login,
'facebook_login': facebook_login,
'can_disconnect': can_disconnect
})
@login_required
def password(request):
if request.user.has_usable_password():
PasswordForm = PasswordChangeForm
else:
PasswordForm = AdminPasswordChangeForm
if request.method == 'POST':
form = PasswordForm(request.user, request.POST)
if form.is_valid():
form.save()
update_session_auth_hash(request, form.user)
messages.success(request, 'Your password was successfully updated!')
return redirect('password')
else:
messages.error(request, 'Please correct the error below.')
else:
form = PasswordForm(request.user)
return render(request, 'core/password.html', {'form': form})
Note that this password view handles both Set password and Change password.
core/settings.html
{% extends 'base.html' %}
{% block content %}
<h2>Settings</h2>
<h3>GitHub</h3>
{% if github_login %}
<p>Connected as <a href="https://github.com/{{ github_login.extra_data.login }}/" target="_blank">{{ github_login.extra_data.login }}</a></p>
{% if can_disconnect %}
<form method="post" action="{% url 'social:disconnect' 'github' %}">
{% csrf_token %}
<button type="submit">Disconnect from GitHub</button>
</form>
{% else %}
<button type="button" disabled>Disconnect from GitHub</button>
<p style="color: red">You must <a href="{% url 'password' %}">define a password</a> for your account before disconnecting from Github.</p>
{% endif %}
{% else %}
<a href="{% url 'social:begin' 'github' %}">Connect to GitHub</a>
{% endif %}
<h3>Twitter</h3>
{% if twitter_login %}
<p>Connected as <a href="https://twitter.com/{{ twitter_login.extra_data.access_token.screen_name }}/" target="_blank">@{{ twitter_login.extra_data.access_token.screen_name }}</a></p>
{% if can_disconnect %}
<form method="post" action="{% url 'social:disconnect' 'twitter' %}">
{% csrf_token %}
<button type="submit">Disconnect from Twitter</button>
</form>
{% else %}
<button type="button" disabled>Disconnect from Twitter</button>
<p style="color: red">You must <a href="{% url 'password' %}">define a password</a> for your account before disconnecting from Twitter.</p>
{% endif %}
{% else %}
<a href="{% url 'social:begin' 'twitter' %}">Connect to Twitter</a>
{% endif %}
<h3>Facebook</h3>
{% if facebook_login %}
<p>Connected as <a href="https://facebook.com/{{ facebook_login.extra_data.id }}/" target="_blank">{{ facebook_login.extra_data.id }}</a></p>
{% if can_disconnect %}
<form method="post" action="{% url 'social:disconnect' 'facebook' %}">
{% csrf_token %}
<button type="submit">Disconnect from Facebook</button>
</form>
{% else %}
<button type="button" disabled>Disconnect from Facebook</button>
<p style="color: red">You must <a href="{% url 'password' %}">define a password</a> for your account before disconnecting from Facebook.</p>
{% endif %}
{% else %}
<a href="{% url 'social:begin' 'facebook' %}">Connect to Facebook</a>
{% endif %}
{% endblock %}
If you look close, it’s just repetitive work. Basically we are showing that if the account is connected with one of the providers, and giving the option to disconnect.
Finally, the password view looks like:
password.html
{% extends 'base.html' %}
{% block content %}
<h2>Change Password</h2>
{% if not user.has_usable_password %}
<p style="color: red">You have not defined a password yet.</p>
{% endif %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Save changes</button>
</form>
{% endblock %}
The /settings/ page will look like this:
If you disconnect from GitHub for example, we are forcing the user to set a password before disconnecting from GitHub, avoiding him/her to be locked out.
Conclusion
Integrating social authentication into your Django application using django-social-auth
can greatly enhance the user experience and simplify registration and login processes. Users can access your site using their social media credentials, saving them the trouble of creating yet another account.
Remember to secure your API keys and secrets, and ensure that your social authentication setup complies with best security practices. Additionally, you can customize the templates and views to fit your application’s design and requirements.
By following the steps outlined in this tutorial, you can successfully integrate social authentication into your Django project and provide a more convenient and seamless experience for your users.
Find this project on Github.
Blogs You Might Like to Read!
- Folder and Directory Structure for Django Project: Best Practices
- Django Best Practices for Building Robust Web Applications
- How To Send Email in Django and DRF
- How to Create RBAC in Django with Multiple Users Types
- Django User Registration with Email Confirmation
- How to Protect Sensitive Data in Python Projects like Django and Flask