本文目录导读:
Django 提供了强大且安全的用户认证系统,实现起来非常方便,主要分为内置认证(快速实现登录/注册)和自定义认证(扩展字段或登录方式)。
以下是 Django 用户认证的完整实现指南:
Django 内置认证系统(最常用)
Django 自带 django.contrib.auth 应用,默认使用用户名 + 密码认证。
基础配置(通常默认已配置)
检查 settings.py 中 INSTALLED_APPS 和 MIDDLEWARE:
INSTALLED_APPS = [
# ...
'django.contrib.auth', # 认证框架
'django.contrib.contenttypes', # permission系统依赖
# ...
]
MIDDLEWARE = [
# ...
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
# ...
]
执行迁移(创建 auth 相关表):
python manage.py migrate
创建用户(注册)
通常通过 User.objects.create_user() 方法创建(密码会自动加密):
from django.contrib.auth.models import User
from django.shortcuts import render, redirect
def register(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
email = request.POST['email']
# 创建用户
user = User.objects.create_user(username=username,
password=password,
email=email)
# 可以直接登录(注册后自动登录)
from django.contrib.auth import login
login(request, user)
return redirect('home')
return render(request, 'register.html')
用户登录
使用 authenticate() 验证,再用 login() 建立会话:
from django.contrib.auth import authenticate, login
def user_login(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) # 创建用户session
return redirect('home')
else:
# 登录失败
error_msg = '用户名或密码错误'
return render(request, 'login.html', {'error': error_msg})
return render(request, 'login.html')
退出登录
from django.contrib.auth import logout
def user_logout(request):
logout(request) # 清除session
return redirect('login')
在模板中判断用户状态
Django 会在模板中提供 {{ user }} 对象:
<!-- 在模板中 -->
{% if user.is_authenticated %}
<p>欢迎,{{ user.username }}!</p>
<a href="{% url 'logout' %}">退出</a>
{% else %}
<a href="{% url 'login' %}">登录</a>
<a href="{% url 'register' %}">注册</a>
{% endif %}
视图保护(要求登录才能访问)
from django.contrib.auth.decorators import login_required
@login_required(login_url='/login/') # 未登录跳转到登录页
def dashboard(request):
# 只有登录用户能访问
return render(request, 'dashboard.html')
或者在类视图中:
from django.contrib.auth.mixins import LoginRequiredMixin
class ProfileView(LoginRequiredMixin, View):
login_url = '/login/'
# ...
使用 Django 内置的 LoginView(更简洁)
Django 提供了现成的类视图,无需手写表单验证逻辑。
在 urls.py 中直接引用
# urls.py
from django.urls import path
from django.contrib.auth.views import LoginView, LogoutView
from . import views
urlpatterns = [
path('login/', LoginView.as_view(template_name='login.html'), name='login'),
path('logout/', LogoutView.as_view(next_page='login'), name='logout'),
path('register/', views.register, name='register'),
]
创建 login.html 模板
注意:表单字段名必须为 username 和 password:
<!-- login.html -->
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<!-- 或手动写 -->
<input type="text" name="username" placeholder="用户名">
<input type="password" name="password" placeholder="密码">
<button type="submit">登录</button>
</form>
- 登录成功默认跳转到
settings.LOGIN_REDIRECT_URL(默认/accounts/profile/),建议在settings.py中设置:LOGIN_REDIRECT_URL = '/home/' # 登录后跳转首页 LOGOUT_REDIRECT_URL = '/login/' # 退出后跳转登录页
自定义用户模型(扩展字段)
如果需要添加手机号、头像等额外字段,推荐使用继承 AbstractUser 的方式。
创建自定义用户模型
# models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
# 继承已有字段(username, password, email...)
phone = models.CharField(max_length=11, unique=True)
avatar = models.ImageField(upload_to='avatars/', blank=True)
bio = models.TextField(blank=True)
def __str__(self):
return self.username
修改 settings.py
# settings.py AUTH_USER_MODEL = 'myapp.CustomUser' # 必须在使用前设置!
创建自定义表单(注册时使用)
# forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from .models import CustomUser
class CustomUserCreationForm(UserCreationForm):
class Meta:
model = CustomUser
fields = ('username', 'email', 'phone', 'password1', 'password2')
注册视图使用新表单
def register(request):
if request.method == 'POST':
form = CustomUserCreationForm(request.POST)
if form.is_valid():
user = form.save() # 直接保存
login(request, user)
return redirect('home')
else:
form = CustomUserCreationForm()
return render(request, 'register.html', {'form': form})
自定义认证后端(如邮箱登录)
如果要实现“用邮箱或手机号登录”,需要自定义 authentication backend。
# authentication.py (在app根目录创建)
from django.contrib.auth.backends import BaseBackend
from django.contrib.auth import get_user_model
User = get_user_model()
class EmailBackend(BaseBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
# 这里 username 可能是邮箱
try:
user = User.objects.get(email=username) # 按邮箱查找
except User.DoesNotExist:
return None
if user.check_password(password):
return user
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
在 settings.py 中注册:
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend', # 保留用户名登录
'myapp.authentication.EmailBackend', # 新增邮箱登录
]
authenticate(request, username='user@example.com', password='...') 也能登录。
密码重置(忘记密码)
Django 内置了完整的密码重置流程:
# urls.py
from django.contrib.auth import views as auth_views
urlpatterns = [
# 密码重置:输入邮箱 -> 发送邮件 -> 点击链接 -> 设置新密码
path('password_reset/',
auth_views.PasswordResetView.as_view(template_name='password_reset.html'),
name='password_reset'),
path('password_reset/done/',
auth_views.PasswordResetDoneView.as_view(template_name='password_reset_done.html'),
name='password_reset_done'),
path('reset/<uidb64>/<token>/',
auth_views.PasswordResetConfirmView.as_view(template_name='password_reset_confirm.html'),
name='password_reset_confirm'),
path('reset/done/',
auth_views.PasswordResetCompleteView.as_view(template_name='password_reset_complete.html'),
name='password_reset_complete'),
]
在 settings.py 配置邮箱发送(开发环境可用控制台输出):
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' # 控制台查看邮件
最佳实践建议
- 不要手写密码哈希:使用
create_user()或set_password(),Django 会自动加盐哈希。 - 使用通用视图:登录/密码重置等直接用
LoginView、PasswordResetView,减少重复代码。 - 始终使用 HTTPS:生产环境密码传输必须加密。
- 自定义用户模型尽早做:如果项目可能扩展用户字段,在第一次迁移前就设置好
AUTH_USER_MODEL,否则很难修改。
完整示例项目结构
myproject/
├── myapp/
│ ├── models.py → CustomUser (可选项)
│ ├── forms.py → 自定义注册表单
│ ├── authentication.py → 自定义后端 (可选项)
│ ├── views.py → register, profile, login 等
│ ├── urls.py → 路由
│ └── templates/
│ └── registration/
│ ├── login.html
│ └── register.html
├── myproject/
│ └── settings.py → AUTH_USER_MODEL, LOGIN_REDIRECT_URL
└── manage.py
如果你只是需要一个简单的登录/注册页面,用 方案一(内置 auth) 最快;如果需要微信登录、OAuth,可以配合 django-allauth 库,需要我深入某个部分吗?
标签: 认证系统