1. Install dependencies

pip install "civic-auth[django]"

2. Configure your App

Add Civic Auth configuration to your Django settings:

# settings.py

CIVIC_AUTH = {
    "client_id": "...",  # Client ID from auth.civic.com
    "redirect_url": "http://localhost:8000/auth/callback",  # change to your domain when deploying
    "post_logout_redirect_url": "http://localhost:8000/"  # The postLogoutRedirectUrl is the URL where the user will be redirected after successfully logging out from Civic's auth server.
}

Note: redirect_url and post_logout_redirect_url must be absolute URLs.

3. Add Middleware

Add the Civic Auth middleware to your Django middleware stack:

# settings.py

MIDDLEWARE = [
    # Add Civic Auth middleware
    'civic_auth.integrations.django.CivicAuthMiddleware',
]

4. Add URL Patterns

Include the Civic Auth URLs in your project:

# urls.py

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

urlpatterns = [
    # Add Civic Auth URLs
    path('', include(get_auth_urls())),
    # Your other URLs...
]

This adds the following routes:

  • /auth/login - Initiates the login flow
  • /auth/callback - Handles the OAuth callback
  • /auth/logout - Logs the user out

5. Protect Views

Use the civic_auth_required decorator to protect views:

# views.py

from django.http import HttpResponse
from civic_auth.integrations.django import civic_auth_required

@civic_auth_required
def protected_view(request):
    return HttpResponse("This view requires authentication!")

6. Access User Information

The authenticated user is available via request.civic_user:

from django.http import JsonResponse
from civic_auth.integrations.django import civic_auth_required

@civic_auth_required
def profile(request):
    user = request.civic_user
    return JsonResponse({
        "id": user.id,
        "email": user.email,
        "name": user.name,
        "picture": user.picture
    })

7. Template Context

Access the user in templates:

# views.py
from django.shortcuts import render
from civic_auth.integrations.django import civic_auth_required

@civic_auth_required
def dashboard(request):
    return render(request, 'dashboard.html', {
        'civic_user': request.civic_user
    })
<!-- templates/dashboard.html -->
{% if civic_user %}
    <p>Welcome, {{ civic_user.name }}!</p>
    <img src="{{ civic_user.picture }}" alt="Profile picture">
{% endif %}

8. API Views

For Django REST Framework compatibility:

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({
        "id": user.id,
        "email": user.email,
        "name": user.name
    })

PKCE and Client Secrets

Civic Auth uses PKCE (Proof Key for Code Exchange), to protect users and clients from unauthorized access to user information. This, alongside domain registration for apps in production environments, mean that you don’t need to provide a client secret in your backend.

When using the Civic Auth SDK, PKCE is handled entirely by the library.