Agent Skills: django-allauth

Django authentication - local accounts, social OAuth, registration, email verification, MFA, session management

UncategorizedID: CodeAtCode/oss-ai-skills/django-allauth

Install this agent skill to your local

pnpm dlx add-skill https://github.com/CodeAtCode/oss-ai-skills/tree/HEAD/frameworks/django-allauth

Skill Files

Browse the full folder contents for django-allauth.

Download Skill

Loading file tree…

frameworks/django-allauth/SKILL.md

Skill Metadata

Name
django-allauth
Description
"Django authentication - local accounts, social OAuth, registration, email verification, MFA, session management"

django-allauth

Django authentication package.

Overview

django-allauth is a reusable Django app for local and social authentication. It handles signup, login, logout, email verification, and integrates with many OAuth providers.

Key Features:

  • Local account management (signup, login, password reset)
  • OAuth providers (Google, GitHub, Facebook, etc.)
  • Email verification
  • Multi-factor authentication (TOTP, WebAuthn)
  • Headless REST API support
  • Session management
  • Custom adapters

Installation

pip install django-allauth

# With optional dependencies
pip install django-allauth[socialaccount]
pip install django-allauth[mfa]

Quick Start

settings.py

INSTALLED_APPS = [
    # Required apps
    'django.contrib.auth',
    'django.contrib.messages',
    'django.contrib.sites',
    
    # allauth
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
]

# Authentication backends
AUTHENTICATION_BACKENDS = [
    'allauth.account.auth_backends.AuthenticationBackend',
]

# Site ID
SITE_ID = 1

# allauth settings
ACCOUNT_AUTHENTICATION_METHOD = 'email'  # or 'username'
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_EMAIL_VERIFICATION = 'mandatory'  # or 'optional', 'none'

LOGIN_REDIRECT_URL = '/'
ACCOUNT_LOGOUT_REDIRECT_URL = '/'

urls.py

from django.urls import path, include

urlpatterns = [
    path('accounts/', include('allauth.urls')),
]

Local Authentication

Signup

# views.py
from allauth.account.views import SignupView

# Uses built-in signup form
# POST /accounts/signup/

Login

# POST /accounts/login/
# Uses built-in login form

# With remember me
# POST /accounts/login/ with remember=true

Logout

# POST /accounts/logout/
# Clears session

Password Management

# Password change: POST /accounts/password/change/
# Password set: POST /accounts/password/set/
# Password reset: POST /accounts/password/reset/
# Password reset confirm: POST /accounts/password/reset/confirm/

Email Configuration

Settings

# Email backend
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

# allauth email settings
ACCOUNT_EMAIL_NOTIFICATIONS = True
EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL = '/'
EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL = '/'

Custom Email Templates

templates/account/email/
├── email_confirmation_subject.txt
├── email_confirmation_message.txt
├── email_confirmation_signup_message.txt
├── password_reset_key_message.txt
└── ...

Sending Emails Manually

from allauth.account.models import EmailAddress

# Get user's verified emails
emails = EmailAddress.objects.filter(
    user=user,
    verified=True
)

# Send via allauth adapter
from allauth.account.adapter import get_adapter
adapter = get_adapter()
adapter.send_mail(
    'account/email/custom_subject.txt',
    user,
    {'context': 'variables'},
    [user.email]
)

OAuth Providers

Google Setup

# settings.py
INSTALLED_APPS += [
    'allauth.socialaccount.providers.google',
]

# Social app in admin:
# Add SocialApp with Google provider
# Client ID and Secret from Google Cloud Console

GitHub Setup

INSTALLED_APPS += [
    'allauth.socialaccount.providers.github',
]

Custom Provider

# myapp/providers.py
from allauth.socialaccount.providers.base import Provider
from allauth.socialaccount.providers.oauth2.provider import ProviderMixin

class MyCustomProvider(ProviderMixin, Provider):
    pass

# myapp/app_settings.py
from allauth.socialaccount import app_settings

provider_classes = [
    'myapp.providers.MyCustomProvider',
]

# settings.py
SOCIALACCOUNT_PROVIDERS = {
    'custom': {
        'APP': {
            'client_id': 'xxx',
            'secret': 'xxx',
            'key': ''
        }
    }
}

Provider Settings

SOCIALACCOUNT_PROVIDERS = {
    'google': {
        'APP': {
            'client_id': 'xxx',
            'secret': 'xxx',
        },
        'SCOPE': ['profile', 'email'],
        'AUTH_PARAMS': {'access_type': 'online'},
    },
    'github': {
        'APP': {
            'client_id': 'xxx',
            'secret': 'xxx',
        },
        'SCOPE': ['user:email'],
    },
}

Multi-Factor Authentication

Enable MFA

INSTALLED_APPS += [
    'allauth.mfa',
]

# Settings
MFA_ENABLED = True
MFA_SUPPORTED_AUTHENTICATORS = [
    'allauth.mfa.authenticators.Totp',
    'allauth.mfa.authenticators.WebAuthn',
    'allauth.mfa.authenticators.RecoveryCodes',
]

TOTP Setup

# Users can set up TOTP via
# GET /mfa/totp/create/
# POST /mfa/totp/activate/

WebAuthn

# WebAuthn/fido2 setup
# GET /mfa/webauthn/create/
# POST /mfa/webauthn/activate/

Recovery Codes

# Generate recovery codes
# GET /mfa/recovery_codes/generate/

REST API (Headless)

Setup

INSTALLED_APPS += [
    'allauth.headless',
]

# Settings
ALLAUTH_HEADLESS_ENABLED = True
ALLAUTH_HEADLESS_TOKEN_STRATEGY = 'allauth.headless.token.StrategyJWT'
ALLAUTH_HEADLESS_TOKEN_JWT_SECRET_KEY = 'your-secret'
ALLAUTH_HEADLESS_TOKEN_JWT_ALGORITHM = 'HS256'

Endpoints

# Signup
POST /headless/signup/
{"email": "user@example.com", "password": "password"}

# Login
POST /headless/authentication/login/
{"email": "user@example.com", "password": "password"}

# Logout
POST /headless/authentication/logout/

# Get current user
GET /headless/users/me/

# Manage emails
GET/POST/DELETE /headless/emails/

# Manage passwords
POST /headless/password/set/
POST /headless/password/change/
POST /headless/password/reset/

Token Strategies

# JWT
ALLAUTH_HEADLESS_TOKEN_STRATEGY = 'allauth.headless.token.StrategyJWT'

# Session-based
ALLAUTH_HEADLESS_TOKEN_STRATEGY = 'allauth.headless.token.StrategySession'

Adapters

Custom Adapter

# myapp/adapter.py
from allauth.account.adapter import DefaultAccountAdapter

class CustomAccountAdapter(DefaultAccountAdapter):
    def is_open_for_signup(self, request):
        return True  # Allow signup
    
    def send_mail(self, template_prefix, email_context, users):
        # Custom email sending
        pass
    
    def get_email_confirmation_redirect_url(self, request):
        return '/confirmed/'
    
    def authenticate(self, request, **credentials):
        # Custom authentication
        return super().authenticate(request, **credentials)

# settings.py
ACCOUNT_ADAPTER = 'myapp.adapter.CustomAccountAdapter'

Social Account Adapter

# myapp/adapter.py
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter

class CustomSocialAccountAdapter(DefaultSocialAccountAdapter):
    def pre_social_login(self, request, sociallogin):
        # Called after login, before creating user
        pass
    
    def populate_user(self, request, sociallogin, data):
        # Populate user fields
        user = sociallogin.user
        user.first_name = data.get('first_name', '')
        user.last_name = data.get('last_name', '')
        return user

# settings.py
SOCIALACCOUNT_ADAPTER = 'myapp.adapter.CustomSocialAccountAdapter'

Signals

Account Signals

from allauth.account import signals

# User signs up
signals.user_signed_up.connect(my_handler, sender=User)

# User logs in
signals.user_logged_in.connect(my_handler, sender=User)

# Email added
signals.email_added.connect(my_handler, sender=User)

# Email confirmed
signals.email_confirmed.connect(my_handler, sender=User)

# Password changed
signals.password_changed.connect(my_handler, sender=User)

# Password reset
signals.password_reset.connect(my_handler, sender=User)

Social Account Signals

from allauth.socialaccount import signals

# Social login successful
signals.social_login.connect(my_handler, sender=SocialLogin)

# Social account added
signals.social_account_added.connect(my_handler, sender=SocialAccount)

# Social account removed
signals.social_account_removed.connect(my_handler, sender=SocialAccount)

# Pre-update
signals.pre_update.connect(my_handler, sender=SocialAccount)

MFA Signals

from allauth.mfa import signals

# MFA enabled
signals.mfa_enabled.connect(my_handler, sender=User)

# MFA disabled
signals.mfa_disabled.connect(my_handler, sender=User)

# Authenticator created
signals.authenticator_created.connect(my_handler, sender=User)

Templates

Custom Templates

templates/
├── account/
│   ├── base.html
│   ├── login.html
│   ├── signup.html
│   ├── logout.html
│   ├── password_change.html
│   ├── password_reset.html
│   ├── password_set.html
│   ├── email/
│   │   ├── email_confirmation_subject.txt
│   │   └── email_confirmation_message.txt
│   └── snippets/
│       └── form.html
├── socialaccount/
│   ├── base.html
│   ├── login.html
│   ├── signup.html
│   ├── connections.html
│   └── snippets/
│       └── provider_list.html
└── mfa/
    ├── index.html
    ├── totp.html
    └── webauthn.html

Template Tags

{% load allauth_tags %}

{# Check if user is verified #}
{% user_verified request.user %}

{# Social account connections #}
{% socialaccount_providers %}

{# Login URL #}
{% provider_login_url "google" %}

Best Practices

1. Use Adapter for Customization

# Instead of modifying allauth, use adapter
ACCOUNT_ADAPTER = 'myapp.adapter.CustomAccountAdapter'

2. Enable HTTPS

# In production
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True

3. Rate Limiting

# Allauth has rate limiting built-in
ACCOUNT_RATE_LIMITS = {
    'signup': '5/hour',
    'password_reset': '3/hour',
}

4. Email Verification

# Require verification
ACCOUNT_EMAIL_VERIFICATION = 'mandatory'

# Or optional
ACCOUNT_EMAIL_VERIFICATION = 'optional'

Examples

Custom Signup Form

# forms.py
from allauth.account.forms import SignupForm

class CustomSignupForm(SignupForm):
    first_name = forms.CharField(max_length=30)
    last_name = forms.CharField(max_length=30)
    
    def save(self, request):
        user = super().save(request)
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.save()
        return user

# views.py
from allauth.account.views import SignupView
from .forms import CustomSignupForm

class CustomSignupView(SignupView):
    form_class = CustomSignupForm

# urls.py
path('accounts/signup/', CustomSignupView.as_view(), name='account_signup')

Require Verified Email

# myapp/middleware.py
from django.shortcuts import redirect
from allauth.account.models import EmailAddress

def verified_email_required(get_response):
    def middleware(request):
        if request.user.is_authenticated:
            email = EmailAddress.objects.filter(
                user=request.user,
                verified=True
            ).exists()
            if not email:
                return redirect('/accounts/verify-email/')
        return get_response(request)
    return middleware

# settings.py
MIDDLEWARE += ['myapp.middleware.verified_email_required']

References

  • Official Documentation: https://docs.allauth.org/
  • GitHub Repository: https://github.com/pennersr/django-allauth
  • Stack Overflow: https://stackoverflow.com/questions/tagged/django-allauth