Django Social Auth Login – Facebook, Twitter and GitHub

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:

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_URLLOGOUT_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.

How to add Facebook login in Django Application

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:

How to add Facebook login in Django Application

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

How to add Facebook login in Django Application

You will be redirected to facebook to grant access, click on continue. And there you go!!!!

How to add social login in Django Application

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:

How to add Twitter login in Django Application

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:

Twitter App Register for Django

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.

How to add Twitter login in Django Application

You will be redirected to Twitter to grant access, click on continue. And there you go!!!!

DJango social auth homepage

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:

How to add GitHub login in Django Application

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:

How to add GitHub login in Django Application

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:

How to add GitHub login in Django Application

After clicking on Login with GitHub it will redirect to Authorization link, click on Authorize Application. And you are good to go.

DJango social auth homepage

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:

Django Social Login Settings Page

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!