Skip to main content

Django Social Authentication

Authentication is a critical part of most web applications, and offering users the ability to sign in with their existing social accounts can greatly improve user experience. In this guide, we'll explore how to implement social authentication in Django using popular providers like Google, Facebook, and GitHub.

Introduction to Social Authentication

Social authentication allows users to log into your application using their existing accounts from social platforms like Google, Facebook, Twitter, or GitHub. This approach has several benefits:

  • Simplified User Experience: Users don't need to create and remember another password
  • Higher Conversion Rates: Reduces friction in the signup process
  • Enhanced Trust: Leverages the security systems of established platforms
  • Access to User Data: With permission, you can access profile information from these platforms

Django doesn't provide social authentication out of the box, but there are excellent third-party packages that make it easy to implement.

Setting Up Social Authentication with django-allauth

We'll use the popular django-allauth package, which provides a set of Django applications that help with authentication, registration, and account management.

Step 1: Install Required Packages

First, let's install the necessary packages:

bash
pip install django-allauth

Step 2: Configure Django Settings

Add the following to your settings.py file:

python
INSTALLED_APPS = [
# Django built-in apps
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites', # Required for allauth

# Allauth apps
'allauth',
'allauth.account',
'allauth.socialaccount',

# Include the providers you want to enable
'allauth.socialaccount.providers.google',
'allauth.socialaccount.providers.facebook',
'allauth.socialaccount.providers.github',

# Your apps
'your_app_name',
]

# Authentication backends
AUTHENTICATION_BACKENDS = [
# Django default
'django.contrib.auth.backends.ModelBackend',

# Required for allauth
'allauth.account.auth_backends.AuthenticationBackend',
]

# Site ID
SITE_ID = 1

# Provider specific settings
SOCIALACCOUNT_PROVIDERS = {
'google': {
'APP': {
'client_id': 'YOUR_CLIENT_ID',
'secret': 'YOUR_SECRET_KEY',
'key': '',
},
'SCOPE': ['profile', 'email'],
'AUTH_PARAMS': {'access_type': 'online'},
},
'facebook': {
'APP': {
'client_id': 'YOUR_CLIENT_ID',
'secret': 'YOUR_SECRET_KEY',
'key': '',
},
'METHOD': 'oauth2',
},
'github': {
'APP': {
'client_id': 'YOUR_CLIENT_ID',
'secret': 'YOUR_SECRET_KEY',
'key': '',
},
},
}

# Redirect URLs
LOGIN_REDIRECT_URL = 'home' # Redirect after successful login
ACCOUNT_LOGOUT_REDIRECT_URL = 'account_login' # Redirect after logout

Step 3: Update Your URLs

Add the allauth URLs to your project's urls.py file:

python
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
path('admin/', admin.site.urls),
path('accounts/', include('allauth.urls')),
# Your other URLs
path('', include('your_app_name.urls')),
]

Step 4: Set Up OAuth Applications with Providers

For each social provider you want to use, you'll need to create an application in their developer console and obtain OAuth credentials.

Google OAuth Setup

  1. Go to the Google Developer Console
  2. Create a new project
  3. Navigate to "APIs & Services" > "Credentials"
  4. Create OAuth client ID credentials
  5. Set the authorized redirect URI to http://yourdomain.com/accounts/google/login/callback/ (for local development, use http://localhost:8000/accounts/google/login/callback/)

Facebook OAuth Setup

  1. Go to the Facebook for Developers
  2. Create a new app
  3. Navigate to "Settings" > "Basic"
  4. Add your app domain and privacy policy URL
  5. Set the OAuth redirect URI to http://yourdomain.com/accounts/facebook/login/callback/

GitHub OAuth Setup

  1. Go to your GitHub Settings
  2. Navigate to "Developer settings" > "OAuth Apps"
  3. Create a new OAuth application
  4. Set the authorization callback URL to http://yourdomain.com/accounts/github/login/callback/

Step 5: Run Migrations

After configuring the settings, run migrations to create the necessary database tables:

bash
python manage.py migrate

Step 6: Create a Site in Admin

  1. Create a superuser if you haven't already: python manage.py createsuperuser
  2. Run the server: python manage.py runserver
  3. Go to the admin interface at http://localhost:8000/admin
  4. Navigate to "Sites" and update the default site's domain and display name

Creating Login Templates

Now, let's create templates for our login page. Create a directory structure like templates/account/ in your project, and add a login template:

html
<!-- templates/account/login.html -->
{% extends "base.html" %}

{% load i18n %}
{% load account socialaccount %}

{% block head_title %}{% trans "Sign In" %}{% endblock %}

{% block content %}
<div class="container">
<h1 class="mt-4">{% trans "Sign In" %}</h1>

<!-- Standard Django Login Form -->
<form class="login mt-3" method="POST" action="{% url 'account_login' %}">
{% csrf_token %}
{{ form.as_p }}
{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
{% endif %}
<button class="btn btn-primary" type="submit">{% trans "Sign In" %}</button>
</form>

<!-- Social Authentication Section -->
<div class="mt-4">
<h4>{% trans "Or sign in with:" %}</h4>
<div class="d-flex gap-2 mt-3">
{% get_providers as socialaccount_providers %}
{% for provider in socialaccount_providers %}
<a href="{% provider_login_url provider.id process='login' %}"
class="btn btn-outline-dark">
{{ provider.name }}
</a>
{% endfor %}
</div>
</div>

<p class="mt-3">
{% trans "Don't have an account?" %}
<a href="{% url 'account_signup' %}">{% trans "Sign up" %}</a>
</p>
</div>
{% endblock %}

Testing Social Authentication

Run your server with python manage.py runserver and navigate to http://localhost:8000/accounts/login/ to see the login page with social buttons. Try logging in with one of the configured providers.

Real-World Example: Customizing User Profile After Social Login

Often, you'll want to customize the user profile after they sign in with a social account. For example, you might want to create a profile for new users or sync information from their social profiles.

Here's how to handle that with django-allauth signals:

python
# In your app's models.py
from django.db import models
from django.contrib.auth.models import User

class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.TextField(max_length=500, blank=True)
profile_picture = models.URLField(blank=True)

# In your app's signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from allauth.account.signals import user_signed_up
from allauth.socialaccount.models import SocialAccount
from .models import Profile

@receiver(user_signed_up)
def create_user_profile(request, user, **kwargs):
"""Create a user profile when a new user signs up."""
Profile.objects.get_or_create(user=user)

# If the user signed up through a social account, try to get their profile picture
try:
social_account = SocialAccount.objects.filter(user=user).first()
if social_account:
if social_account.provider == 'google':
# Extract profile picture from Google
extra_data = social_account.extra_data
if 'picture' in extra_data:
profile = Profile.objects.get(user=user)
profile.profile_picture = extra_data['picture']
profile.save()
elif social_account.provider == 'github':
# Extract profile picture from GitHub
extra_data = social_account.extra_data
if 'avatar_url' in extra_data:
profile = Profile.objects.get(user=user)
profile.profile_picture = extra_data['avatar_url']
profile.save()
except Exception as e:
# Handle exceptions gracefully
print(f"Error setting profile picture: {e}")

Make sure to register your signals by creating an apps.py file in your app:

python
from django.apps import AppConfig

class YourAppConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'your_app_name'

def ready(self):
import your_app_name.signals

And update the __init__.py in your app:

python
default_app_config = 'your_app_name.apps.YourAppConfig'

Advanced Customization

Custom Adapter for Social Accounts

You can create a custom adapter to handle social account logins:

python
# In a file like adapters.py
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter

class CustomSocialAccountAdapter(DefaultSocialAccountAdapter):
def pre_social_login(self, request, sociallogin):
"""
Invoked just after a user successfully authenticates via a social provider,
but before the login is actually processed.
"""
# Can be used to perform additional validation or modify user data
user = sociallogin.user

if not user.email:
# Handle case where social provider didn't return an email
pass

# You can also connect social accounts to existing users
if user.id is None: # User hasn't been saved yet
try:
# Look for existing user with same email
existing_user = self.get_user_model().objects.get(email=user.email)
sociallogin.connect(request, existing_user) # Connect to existing user
except self.get_user_model().DoesNotExist:
pass

Then update your settings.py to use this adapter:

python
SOCIALACCOUNT_ADAPTER = 'your_app_name.adapters.CustomSocialAccountAdapter'

Provider-Specific Settings

Different providers require different settings. Here are some examples:

python
SOCIALACCOUNT_PROVIDERS = {
'google': {
'APP': {
'client_id': 'YOUR_CLIENT_ID',
'secret': 'YOUR_SECRET_KEY',
'key': '',
},
'SCOPE': ['profile', 'email'],
'AUTH_PARAMS': {'access_type': 'online'},
},
'facebook': {
'METHOD': 'oauth2',
'SDK_URL': '//connect.facebook.net/{locale}/sdk.js',
'SCOPE': ['email', 'public_profile'],
'AUTH_PARAMS': {'auth_type': 'reauthenticate'},
'INIT_PARAMS': {'cookie': True},
'FIELDS': [
'id',
'first_name',
'last_name',
'middle_name',
'name',
'name_format',
'picture',
'short_name'
],
'EXCHANGE_TOKEN': True,
'LOCALE_FUNC': 'path.to.callable',
'VERIFIED_EMAIL': False,
'VERSION': 'v13.0',
'APP': {
'client_id': 'YOUR_CLIENT_ID',
'secret': 'YOUR_SECRET_KEY',
'key': '',
},
}
}

Security Considerations

When implementing social authentication, keep these security considerations in mind:

  1. Always use HTTPS for production sites
  2. Keep OAuth client secrets secure and out of version control
  3. Understand what user data you're collecting and comply with privacy regulations
  4. Consider using environment variables for storing OAuth credentials
python
# Using environment variables for OAuth credentials
import os

SOCIALACCOUNT_PROVIDERS = {
'google': {
'APP': {
'client_id': os.environ.get('GOOGLE_CLIENT_ID'),
'secret': os.environ.get('GOOGLE_CLIENT_SECRET'),
'key': '',
},
},
}

Summary

In this guide, we've learned how to implement social authentication in Django using the django-allauth package:

  1. We set up configuration for multiple providers including Google, Facebook, and GitHub
  2. We created templates for the login page that include social login buttons
  3. We explored customizing user profiles with data from social accounts
  4. We discussed advanced customization options and security considerations

Social authentication can significantly improve the user experience of your Django application by simplifying the login process and reducing friction during registration.

Further Resources

Exercises

  1. Implement social authentication with Google in a Django project
  2. Add a profile model that gets populated with data from social profiles
  3. Create a custom adapter that merges accounts when a user signs up with a social account using an email that already exists in your system
  4. Add a feature that lets users connect multiple social accounts to their existing account
  5. Implement a fallback authentication system that works even when social authentication providers are down


If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)