dj-rest-auth Documentation

repository·master·Indexed 23 days ago

https://github.com/imerica/dj-rest-auth

Secure authentication endpoints for Django REST Framework designed for SPAs and mobile applications. Supports Token, Session, and JWT authentication (including HTTP-only cookies), user registration via django-allauth, Multi-Factor Authentication (MFA), and Passkeys (WebAuthn). Includes a full-stack demo featuring a Next.js spa-client and a Django backend.

Tokens
30K
Snippets
81
Records
104
Agent score
82%

What's inside dj-rest-auth

  1. Understand the dj-rest-auth Demo Architecture

    master

    The demo demonstrates a modern Single Page Application (SPA) authentication flow. It is composed of two primary parts:

    1. Backend (demo/backend): A Django project integrating dj-rest-auth, django-allauth, and djangorestframework-simplejwt. It provides REST APIs for registration, login, and Multi-Factor Authentication (MFA).
    2. Frontend (demo/spa-client): A Next.js application that interacts with the backend APIs to implement user flows like registration, login, MFA setup (via QR code), and MFA verification.

    Login Flow Sequence

    1. User provides credentials via the frontend pages.
    2. Frontend sends a login request to dj-rest-auth.
    3. If MFA is enabled, dj-rest-auth responds indicating MFA is required along with an ephemeral token.
    4. The user provides the MFA verification code and the ephemeral token.
    5. dj-rest-auth issues the final Authentication Token or Session.
  2. Configure Login response formats

    master

    The Login endpoint returns different response structures based on your authentication setup:

    • Token Auth: Returns a single key.
    • JWT: Returns access and refresh tokens, plus a user object.
    • JWT with Expiration: If JWT_AUTH_RETURN_EXPIRATION = True, the response also includes access_expiration and refresh_expiration timestamps.
    // JWT Response Example
    {
        "access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
        "refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
        "user": {
            "pk": 1,
            "username": "testuser",
            "email": "test@example.com",
            "first_name": "Test",
            "last_name": "User"
        }
    }
  3. How dj-rest-auth architecture works

    master

    dj-rest-auth acts as an orchestration layer between your Client App (SPA/Mobile) and the underlying Django ecosystem.

    • Client App sends requests to dj-rest-auth views (e.g., LoginView, LogoutView, UserDetailsView).
    • dj-rest-auth processes these requests by interacting with:
      • django.contrib.auth for core authentication logic.
      • djangorestframework-simplejwt for JWT generation and handling.
      • django-allauth for advanced features like password resets and social authentication.

    This architecture allows for secure, standardized REST API endpoints that leverage proven Django libraries.

  4. How the MFA login flow works

    master

    When a user has MFA enabled, the login process changes from a single step to a two-step flow:

    1. Initial Login: The client sends the username and password to the login endpoint. Instead of a full authentication response, the API returns an ephemeral_token and sets mfa_required: true.
    2. MFA Verification: The client takes that ephemeral_token and submits it along with a TOTP code (from an authenticator app) or a recovery code to the MFA verify endpoint.
    3. Final Authentication: Upon successful verification, the API returns the standard authentication response (e.g., Token, JWT, or Session).

    Security Note: The ephemeral_token is short-lived and expires after the duration defined by MFA_EPHEMERAL_TOKEN_TIMEOUT (defaulting to 300 seconds).

  5. Quickstart: Set up dj-rest-auth with Token Authentication

    master

    Follow these steps to build a working authentication API using Django, Django Rest Framework, and dj-rest-auth with standard Token Authentication.

    Prerequisites

    • Python 3.10+
    • Django 4.2+

    1. Installation and Project Setup

    # Create project directory
    mkdir myproject && cd myproject
    
    # Create virtual environment
    python -m venv venv
    source venv/bin/activate  # On Windows: venv\Scripts\activate
    
    # Install dependencies
    pip install django djangorestframework dj-rest-auth
    
    # Create Django project
    django-admin startproject config .

    2. Configuration

    Update config/settings.py: Add the required apps to INSTALLED_APPS and configure REST_FRAMEWORK to use TokenAuthentication.

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        
        # Add these
        'rest_framework',
        'rest_framework.authtoken',
        'dj_rest_auth',
    ]
    
    # Add at the bottom
    REST_FRAMEWORK = {
        'DEFAULT_AUTHENTICATION_CLASSES': [
            'rest_framework.authentication.TokenAuthentication',
        ],
    }

    Update config/urls.py: Include the dj_rest_auth.urls in your URL patterns.

    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('api/auth/', include('dj_rest_auth.urls')),
    ]

    3. Database and User Setup

    # Run migrations
    python manage.py migrate
    
    # Create a test user
    python manage.py createsuperuser --username testuser --email test@example.com
    
    # Start the server
    python manage.py runserver
    mkdir myproject && cd myproject
    python -m venv venv
    source venv/bin/activate
    pip install django djangorestframework dj-rest-auth
    django-admin startproject config .
  6. Security: CSRF and Token Storage best practices

    master

    CSRF Protection

    • Token (Header) & JWT (Header): CSRF-immune because headers are not sent automatically by browsers.
    • JWT (Cookie): Requires CSRF protection. Enable with JWT_AUTH_COOKIE_USE_CSRF.
    • Session: Requires Django CSRF middleware.

    Token Storage

    Never store tokens in localStorage or sessionStorage for SPAs, as they are vulnerable to XSS. Instead, use HTTP-only cookies to prevent JavaScript access.

    REST_AUTH = {
        'JWT_AUTH_HTTPONLY': True,  # Prevent JS access
        'JWT_AUTH_SECURE': True,     # HTTPS only
        'JWT_AUTH_SAMESITE': 'Lax',  # CSRF protection
    }
  7. Refresh JWT Tokens on Activity

    master

    To keep users logged in while they are active, you can use rest_framework_simplejwt settings to automatically rotate refresh tokens.

    In settings.py, enable ROTATE_REFRESH_TOKENS and BLACKLIST_AFTER_ROTATION within the SIMPLE_JWT configuration.

    SIMPLE_JWT = {
        'ROTATE_REFRESH_TOKENS': True,
        'BLACKLIST_AFTER_ROTATION': True,
    }
  8. Register a Passkey

    master

    Passkey registration is a two-step process that requires the user to be currently authenticated.

    1. Begin Registration: Call POST /dj-rest-auth/passkeys/register/begin/. You can optionally provide a name for the credential. The server returns PublicKeyCredentialCreationOptions.
    2. Browser Interaction: Use the browser's navigator.credentials.create() API with the received options.
    3. Complete Registration: Call POST /dj-rest-auth/passkeys/register/complete/ with the resulting credential and an optional name. The server verifies the response and returns the registered credential details (201 Created).
  9. Implement Facebook OAuth login

    master

    To implement Facebook login:

    1. Facebook Developers: Create an app and add the Facebook Login product. Configure Valid OAuth Redirect URIs.
    2. Backend View:
    from allauth.socialaccount.providers.facebook.views import FacebookOAuth2Adapter
    from dj_rest_auth.registration.views import SocialLoginView
    
    class FacebookLogin(SocialLoginView):
        adapter_class = FacebookOAuth2Adapter
    1. URL: Map the view to api/auth/facebook/.

    Note: Unlike Google and GitHub, the Facebook implementation shown here does not explicitly require setting a client_class or callback_url in the view class, though you should ensure your Facebook App settings match your backend configuration.

  10. Require Email Verification Before Login

    master

    To prevent users from logging in until they have verified their email address:

    1. Configure allauth settings in settings.py to make email verification mandatory.
    2. (Optional) Create a CustomLoginSerializer that extends LoginSerializer and overrides validate to check if the user's email is verified. If not, raise a serializers.ValidationError with a custom message.
    # settings.py
    ACCOUNT_EMAIL_REQUIRED = True
    ACCOUNT_EMAIL_VERIFICATION = 'mandatory'
    ACCOUNT_AUTHENTICATION_METHOD = 'email'
    
    # serializers.py (Optional custom error message)
    class CustomLoginSerializer(LoginSerializer):
        def validate(self, attrs):
            attrs = super().validate(attrs)
            user = attrs['user']
            if not user.emailaddress_set.filter(verified=True).exists():
                raise serializers.ValidationError(
                    {'email': 'Please verify your email address before logging in.'}
                )
            return attrs
  11. Enable Passkeys / WebAuthn Authentication

    master

    To enable passwordless authentication using passkeys (e.g., Touch ID, Windows Hello):

    1. Install the package with passkey extras:
      pip install 'dj-rest-auth[with-passkeys]'
    2. Add dj_rest_auth.passkeys to INSTALLED_APPS.
    3. Configure REST_AUTH with PASSKEY_RP_ID, PASSKEY_RP_NAME, and PASSKEY_RP_ORIGINS.
    4. Include dj_rest_auth.passkeys.urls in your urls.py.
    5. Run migrations.

    Available endpoints:

    • POST /api/auth/passkeys/register/begin/: Start passkey registration
    • POST /api/auth/passkeys/register/complete/: Complete passkey registration
    • POST /api/auth/passkeys/login/begin/: Start passkey login
    • POST /api/auth/passkeys/login/complete/: Complete passkey login
    • GET /api/auth/passkeys/: List registered passkeys
    • GET, PATCH, DELETE /api/auth/passkeys/{id}/: Manage individual passkey
    pip install 'dj-rest-auth[with-passkeys]'
  12. Override dj-rest-auth Serializers

    master

    You can replace any of the default serializers by providing the dotted path to your custom serializer class in the REST_AUTH settings dictionary. This allows you to add custom validation, extra fields, or modify the data structure returned by the API.

    Supported serializer keys in REST_AUTH include:

    • LOGIN_SERIALIZER
    • USER_DETAILS_SERIALIZER
    • REGISTER_SERIALIZER
    • JWT_TOKEN_CLAIMS_SERIALIZER
    ```python
    REST_AUTH = {
        'LOGIN_SERIALIZER': 'myapp.serializers.CustomLoginSerializer',
        'USER_DETAILS_SERIALIZER': 'myapp.serializers.CustomUserDetailsSerializer',
        'REGISTER_SERIALIZER': 'myapp.serializers.CustomRegisterSerializer',
        'JWT_TOKEN_CLAIMS_SERIALIZER': 'myapp.serializers.CustomTokenClaimsSerializer',
    }
    ```埋