Complete Authentication Flow#
Setup#
# settings.py
INSTALLED_APPS = [
# ...
'django.contrib.auth',
'django.contrib.sessions',
]
MIDDLEWARE = [
# ...
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
]
User Registration#
# views.py
from django.contrib.auth import login
from django.contrib.auth.forms import UserCreationForm
from django.shortcuts import render, redirect
def register(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save()
login(request, user) # Auto-login after registration
return redirect('home')
else:
form = UserCreationForm()
return render(request, 'registration/register.html', {'form': form})
<!-- templates/registration/register.html -->
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Register</button>
</form>
User Login#
# views.py
from django.contrib.auth import authenticate, login
from django.shortcuts import render, redirect
from django.contrib import messages
def login_view(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
next_url = request.GET.get('next', 'home')
return redirect(next_url)
else:
messages.error(request, 'Invalid credentials')
return render(request, 'registration/login.html')
<!-- templates/registration/login.html -->
<form method="post">
{% csrf_token %}
<input type="text" name="username" placeholder="Username" required>
<input type="password" name="password" placeholder="Password" required>
<button type="submit">Login</button>
</form>
Using Django's Built-in Views#
# urls.py
from django.contrib.auth import views as auth_views
from django.urls import path
urlpatterns = [
path('login/', auth_views.LoginView.as_view(), name='login'),
path('logout/', auth_views.LogoutView.as_view(), name='logout'),
path('register/', register_view, name='register'),
]
Logout#
# views.py
from django.contrib.auth import logout
from django.shortcuts import redirect
def logout_view(request):
logout(request)
return redirect('login')
Check Authentication#
# In views
from django.contrib.auth.decorators import login_required
@login_required
def profile(request):
return render(request, 'profile.html')
# In templates
{% if user.is_authenticated %}
<p>Welcome, {{ user.username }}!</p>
{% else %}
<p>Please log in.</p>
{% endif %}
Password Reset Flow#
# urls.py
from django.contrib.auth import views as auth_views
urlpatterns = [
path('password-reset/',
auth_views.PasswordResetView.as_view(
template_name='registration/password_reset.html',
email_template_name='registration/password_reset_email.html',
subject_template_name='registration/password_reset_subject.txt'
),
name='password_reset'),
path('password-reset/done/',
auth_views.PasswordResetDoneView.as_view(
template_name='registration/password_reset_done.html'
),
name='password_reset_done'),
path('password-reset-confirm/<uidb64>/<token>/',
auth_views.PasswordResetConfirmView.as_view(
template_name='registration/password_reset_confirm.html'
),
name='password_reset_confirm'),
path('password-reset-complete/',
auth_views.PasswordResetCompleteView.as_view(
template_name='registration/password_reset_complete.html'
),
name='password_reset_complete'),
]
Custom User Model#
# models.py
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
phone = models.CharField(max_length=20, blank=True)
bio = models.TextField(blank=True)
def __str__(self):
return self.username
# settings.py
AUTH_USER_MODEL = 'myapp.User'
Session Management#
# settings.py
SESSION_ENGINE = 'django.contrib.sessions.backends.db'
SESSION_COOKIE_AGE = 86400 # 24 hours
SESSION_COOKIE_SECURE = True # HTTPS only
SESSION_COOKIE_HTTPONLY = True
Permission Checks#
# views.py
from django.contrib.auth.decorators import permission_required
from django.core.exceptions import PermissionDenied
@permission_required('myapp.can_publish', raise_exception=True)
def publish_post(request, pk):
post = get_object_or_404(Post, pk=pk)
post.is_published = True
post.save()
return redirect('post_detail', pk=pk)
# Or in view
def edit_post(request, pk):
post = get_object_or_404(Post, pk=pk)
if post.author != request.user and not request.user.is_staff:
raise PermissionDenied
# Edit logic...
Class-Based View Authentication#
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
class PostCreateView(LoginRequiredMixin, CreateView):
model = Post
fields = ['title', 'content']
login_url = '/login/'
redirect_field_name = 'next'
class PostUpdateView(PermissionRequiredMixin, UpdateView):
model = Post
permission_required = 'myapp.change_post'
fields = ['title', 'content']
Next: OAuth with Google