Sobes.tech
Middle+
198

How to implement a custom authentication system in Django?

Answer from AI

sobes.tech AI

To implement a custom authentication system in Django, follow these steps:

  1. Create a custom user model.

    Inherit from AbstractUser or AbstractBaseUser and define the necessary fields for your system. AbstractUser includes standard fields like username, first_name, last_name, email, is_staff, is_active, date_joined. AbstractBaseUser provides only basic authentication functionality and requires you to define all fields yourself.

    // users/models.py
    from django.contrib.auth.models import AbstractUser
    from django.db import models
    
    class CustomUser(AbstractUser):
        # Additional fields, e.g., phone number
        phone_number = models.CharField(max_length=15, blank=True, null=True)
    
        # Additional settings if needed
        # USERNAME_FIELD = 'email' # Use email for login
        # REQUIRED_FIELDS = ['first_name', 'last_name'] # Required fields when creating a user
    
        def __str__(self):
            return self.username
    
  2. Configure Django to use the custom user model.

    In your settings.py, set AUTH_USER_MODEL to your custom model.

    // settings.py
    AUTH_USER_MODEL = 'users.CustomUser' # Your_app.Your_Custom_User_Model
    
  3. Create forms for registration and authentication.

    Use UserCreationForm for registration and AuthenticationForm for login, inheriting and customizing them as needed. You might need to create your own forms for your custom user model.

    // users/forms.py
    from django import forms
    from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
    from .models import CustomUser
    
    class CustomUserCreationForm(UserCreationForm):
        class Meta(UserCreationForm.Meta):
            model = CustomUser
            fields = ('username', 'email', 'phone_number') # Add your fields
    
    class CustomAuthenticationForm(AuthenticationForm):
        pass # Leave empty if no changes needed
    
  4. Create views to handle forms.

    Use function-based or class-based views to display forms, handle POST requests, authenticate, and logout.

    // users/views.py
    from django.shortcuts import render, redirect
    from django.contrib.auth import login, logout, authenticate
    from .forms import CustomUserCreationForm, CustomAuthenticationForm
    
    def signup_view(request):
        if request.method == 'POST':
            form = CustomUserCreationForm(request.POST)
            if form.is_valid():
                user = form.save()
                login(request, user) # Auto login after registration
                return redirect('home') # Redirect to homepage
        else:
            form = CustomUserCreationForm()
        return render(request, 'users/signup.html', {'form': form})
    
    def login_view(request):
        if request.method == 'POST':
            form = CustomAuthenticationForm(request, data=request.POST)
            if form.is_valid():
                username = form.cleaned_data.get('username')
                password = form.cleaned_data.get('password')
                user = authenticate(username=username, password=password)
                if user is not None:
                    login(request, user)
                    return redirect('home')
            else:
                # Handle authentication errors
                pass
        else:
            form = CustomAuthenticationForm()
        return render(request, 'users/login.html', {'form': form})
    
    def logout_view(request):
        logout(request)
        return redirect('home')
    
  5. Configure URLs.

    Define URLs for registration, login, and logout, linking them to the respective views.

    // users/urls.py
    from django.urls import path
    from . import views
    
    urlpatterns = [
        path('signup/', views.signup_view, name='signup'),
        path('login/', views.login_view, name='login'),
        path('logout/', views.logout_view, name='logout'),
    ]
    

    Include these URLs in your project's main urls.py.

    // your_project/urls.py
    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('accounts/', include('users.urls')), # Include your app's URLs
        # Other URLs
    ]
    
  6. Create HTML templates.

    Create templates for registration and login forms.

    <!-- users/templates/users/signup.html -->
    <h2>Registration</h2>
    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">Register</button>
    </form>
    
    <!-- users/templates/users/login.html -->
    <h2>Login</h2>
    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">Login</button>
    </form>
    
  7. Configure authentication backend if needed.

    If you need to authenticate using other parameters (e.g., email), implement a custom backend.

    // users/backends.py
    from django.contrib.auth.backends import BaseBackend
    from django.contrib.auth import get_user_model
    
    class EmailBackend(BaseBackend):
        def authenticate(self, request, username=None, password=None, **kwargs):
            UserModel = get_user_model()
            try:
                user = UserModel.objects.get(email=username) # Find user by email
            except UserModel.DoesNotExist:
                return None
    
            if user.check_password(password):
                return user
            return None
    
        def get_user(self, user_id):
            UserModel = get_user_model()
            try:
                return UserModel.objects.get(pk=user_id)
            except UserModel.DoesNotExist:
                return None
    

    Add the custom backend to settings.py.

    // settings.py
    AUTHENTICATION_BACKENDS = [
        'users.backends.EmailBackend', # Your custom backend
        'django.contrib.auth.backends.ModelBackend', # Default backend
    ]
    
  8. Database migrations.

    After making changes to the user model, run migrations.

    python manage.py makemigrations users
    python manage.py migrate
    

This approach allows flexible customization of user fields, authentication logic, and form appearance.