Prefer AI-assisted setup? Use our AI prompts for Django to automatically integrate Civic Auth using Claude, ChatGPT, or other AI assistants. Includes a step-by-step video tutorial!

Quick Start

1. Install Dependencies

pip install "civic-auth[django]"

2. Configure Your Django Settings

Add Civic Auth configuration to your Django settings:
# settings.py

CIVIC_AUTH = {
    "client_id": "YOUR_CLIENT_ID",  # Get this from auth.civic.com
    "redirect_url": "http://localhost:8000/auth/callback",
    "post_logout_redirect_url": "http://localhost:8000/"
}

# Add Civic Auth middleware
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    # Add Civic Auth middleware
    'civic_auth.integrations.django.CivicAuthMiddleware',
]

3. Add URL Patterns

Include the Civic Auth URLs in your project:
# urls.py

from django.contrib import admin
from django.urls import path, include
from civic_auth.integrations.django import get_auth_urls

urlpatterns = [
    path('admin/', admin.site.urls),
    # Add Civic Auth URLs
    path('', include(get_auth_urls())),
    # Your other URLs...
    path('', include('your_app.urls')),  # Replace with your app
]

4. Create Basic Views

Create views for your application:
# views.py

from django.http import HttpResponse, JsonResponse
from django.shortcuts import render
from civic_auth.integrations.django import civic_auth_required

def home(request):
    return HttpResponse("""
        <h1>Welcome to My Django App!</h1>
        <p><a href="/auth/login">Login with Civic Auth</a></p>
        <p><a href="/profile">View Profile</a> (requires authentication)</p>
        <p><a href="/dashboard">Dashboard</a> (requires authentication)</p>
    """)

@civic_auth_required
def profile(request):
    user = request.civic_user
    return JsonResponse({
        "message": f"Hello, {user.get('name', 'User')}!",
        "user_info": {
            "id": user.get("id"),
            "email": user.get("email"),
            "name": user.get("name"),
            "picture": user.get("picture")
        }
    })

@civic_auth_required
def dashboard(request):
    user = request.civic_user
    return HttpResponse(f"""
        <h1>Dashboard</h1>
        <p>Welcome, {user.get('name', 'User')}!</p>
        <img src="{user.get('picture', '')}" alt="Profile picture" style="width: 50px; height: 50px; border-radius: 50%;">
        <p>Email: {user.get('email', 'No email')}</p>
        <p><a href="/auth/logout">Logout</a></p>
    """)

def public_page(request):
    return HttpResponse("<h1>Public Page</h1><p>No authentication required</p>")

5. Add URL Patterns for Your Views

# your_app/urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name='home'),
    path('profile/', views.profile, name='profile'),
    path('dashboard/', views.dashboard, name='dashboard'),
    path('public/', views.public_page, name='public'),
]

6. Run Your Django App

python manage.py runserver
Visit http://localhost:8000 and click the login link to test authentication.

How It Works

Authentication Flow

  1. User visits /auth/login - starts the login process
  2. User authenticates with Civic
  3. User gets redirected to /auth/callback - completes authentication
  4. User can now access protected views

Available Routes

  • /auth/login - Start authentication
  • /auth/callback - Handle OAuth callback (auto-created)
  • /auth/logout - Sign out user

Working with User Data

The authenticated user is available via request.civic_user as a dictionary:
@civic_auth_required
def user_info(request):
    user = request.civic_user
    return JsonResponse({
        "id": user.get("id"),
        "email": user.get("email"),
        "name": user.get("name"),
        "picture": user.get("picture")
    })

Protecting Views

Use the @civic_auth_required decorator to protect views:
from civic_auth.integrations.django import civic_auth_required

@civic_auth_required
def protected_view(request):
    user = request.civic_user
    return HttpResponse(f"Hello {user.get('name', 'User')}, this is protected!")

Template Usage

Access the user in Django templates:
# views.py
from django.shortcuts import render
from civic_auth.integrations.django import civic_auth_required

@civic_auth_required
def dashboard_template(request):
    return render(request, 'dashboard.html', {
        'civic_user': request.civic_user
    })
<!-- templates/dashboard.html -->
<!DOCTYPE html>
<html>
<head>
    <title>Dashboard</title>
</head>
<body>
    {% if civic_user %}
        <h1>Welcome, {{ civic_user.name|default:"User" }}!</h1>
        <img src="{{ civic_user.picture }}" alt="Profile picture">
        <p>Email: {{ civic_user.email|default:"No email" }}</p>
        <a href="/auth/logout">Logout</a>
    {% else %}
        <p><a href="/auth/login">Please login</a></p>
    {% endif %}
</body>
</html>

Django REST Framework

For API views with Django REST Framework:
from rest_framework.decorators import api_view
from rest_framework.response import Response
from civic_auth.integrations.django import civic_auth_required

@api_view(['GET'])
@civic_auth_required
def api_profile(request):
    user = request.civic_user
    return Response({
        "authenticated": True,
        "user": {
            "id": user.get("id"),
            "email": user.get("email"),
            "name": user.get("name"),
            "picture": user.get("picture")
        }
    })

@api_view(['GET'])
@civic_auth_required
def api_dashboard(request):
    user = request.civic_user
    return Response({
        "message": f"Welcome to your dashboard, {user.get('name', 'User')}!",
        "user_id": user.get("id")
    })

Complete Example

Here’s a complete working Django project structure:
# settings.py
import os
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent

SECRET_KEY = 'your-secret-key'
DEBUG = True
ALLOWED_HOSTS = []

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'your_app',  # Replace with your app name
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'civic_auth.integrations.django.CivicAuthMiddleware',
]

ROOT_URLCONF = 'your_project.urls'

CIVIC_AUTH = {
    "client_id": "YOUR_CLIENT_ID",  # Replace with your actual client ID
    "redirect_url": "http://localhost:8000/auth/callback",
    "post_logout_redirect_url": "http://localhost:8000/"
}

# Database, static files, etc. (standard Django configuration)
# your_project/urls.py
from django.contrib import admin
from django.urls import path, include
from civic_auth.integrations.django import get_auth_urls

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(get_auth_urls())),
    path('', include('your_app.urls')),
]

Configuration Options

FieldRequiredDescription
client_idYesYour Civic Auth Client ID from auth.civic.com
redirect_urlYesWhere Civic redirects after authentication (must be absolute URL)
post_logout_redirect_urlYesWhere users go after logout (must be absolute URL)
Note: redirect_url and post_logout_redirect_url must be absolute URLs.

Next Steps

  1. Get your Client ID: Sign up at auth.civic.com
  2. Replace YOUR_CLIENT_ID with your actual client ID
  3. Update URLs when deploying to production
  4. Add more protected views as needed
  5. Create templates for better user experience

Authentication Flows

Civic Auth supports multiple OAuth 2.0 authentication methods to provide maximum security for different application architectures.
Need client secret authentication? Civic Auth supports PKCE-only, client secrets, and hybrid PKCE + client secret approaches. See our Authentication Flows guide for detailed comparison.
The examples above use PKCE authentication, which is handled entirely by the Civic Auth SDK and suitable for most applications.