Django认证系统
一、今日学习内容概述
二、用户认证基础实现
2.1 创建自定义用户模型
# accounts/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
phone = models.CharField('手机号', max_length=11, blank=True)
avatar = models.ImageField('头像', upload_to='avatars/', null=True, blank=True)
bio = models.TextField('个人简介', max_length=500, blank=True)
class Meta:
verbose_name = '用户'
verbose_name_plural = verbose_name
def __str__(self):
return self.username
2.2 配置认证设置
# settings.py
AUTH_USER_MODEL = 'accounts.CustomUser'
# 认证相关设置
LOGIN_URL = '/accounts/login/'
LOGIN_REDIRECT_URL = '/'
LOGOUT_REDIRECT_URL = '/accounts/login/'
2.3 实现认证视图
# accounts/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', 'password1', 'password2')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in self.fields.values():
field.widget.attrs['class'] = 'form-control'
# accounts/views.py
from django.shortcuts import render, redirect
from django.contrib.auth import login, logout
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from .forms import CustomUserCreationForm
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, 'accounts/register.html', {'form': form})
@login_required
def profile(request):
return render(request, 'accounts/profile.html')
2.4 创建认证模板
<!-- templates/accounts/login.html -->
{% extends 'base.html' %}
{% block content %}
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card">
<div class="card-body">
<h2 class="card-title text-center">用户登录</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-primary w-100">登录</button>
</form>
<p class="text-center mt-3">
还没有账号?<a href="{% url 'register' %}">立即注册</a>
</p>
</div>
</div>
</div>
</div>
{% endblock %}
三、权限系统实现
3.1 创建自定义权限
# app/models.py
class Article(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
author = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
class Meta:
permissions = [
("can_publish_article", "Can publish article"),
("can_edit_others_article", "Can edit others article"),
]
3.2 权限装饰器使用
# app/views.py
from django.contrib.auth.decorators import permission_required
@permission_required('app.can_publish_article', raise_exception=True)
def publish_article(request):
# 发布文章的逻辑
pass
# 多个权限检查
@permission_required(['app.can_publish_article', 'app.can_edit_others_article'], raise_exception=True)
def edit_article(request):
# 编辑文章的逻辑
pass
# 使用用户测试函数
from django.contrib.auth.decorators import user_passes_test
def email_verified(user):
return user.email and user.is_active
@user_passes_test(email_verified)
def protected_view(request):
# 受保护的视图逻辑
pass
3.3 在模板中使用权限
{% if perms.app.can_publish_article %}
<a href="{% url 'publish_article' %}" class="btn btn-primary">发布文章</a>
{% endif %}
{% if user.has_perm('app.can_edit_others_article') %}
<a href="{% url 'edit_article' article.id %}" class="btn btn-warning">编辑</a>
{% endif %}
四、用户组管理
4.1 创建和管理用户组
# accounts/admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import CustomUser
class CustomUserAdmin(UserAdmin):
list_display = ('username', 'email', 'phone', 'is_staff', 'is_active')
list_filter = ('is_staff', 'is_superuser', 'is_active', 'groups')
fieldsets = UserAdmin.fieldsets + (
('自定义字段', {'fields': ('phone', 'avatar', 'bio')}),
)
admin.site.register(CustomUser, CustomUserAdmin)
# accounts/views.py
from django.contrib.auth.models import Group
from django.contrib.auth.decorators import user_passes_test
@user_passes_test(lambda u: u.is_superuser)
def manage_groups(request):
if request.method == 'POST':
# 创建新用户组
group_name = request.POST.get('group_name')
permissions = request.POST.getlist('permissions')
group = Group.objects.create(name=group_name)
group.permissions.set(permissions)
messages.success(request, f'用户组 {group_name} 创建成功')
return redirect('manage_groups')
groups = Group.objects.all()
return render(request, 'accounts/manage_groups.html', {'groups': groups})
五、认证流程图
六、自定义认证后端
6.1 创建自定义认证后端
# accounts/auth_backends.py
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q
from .models import CustomUser
class EmailOrPhoneBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
try:
# 通过邮箱或手机号查找用户
user = CustomUser.objects.get(
Q(username=username) |
Q(email=username) |
Q(phone=username)
)
if user.check_password(password):
return user
return None
except CustomUser.DoesNotExist:
return None
6.2 配置认证后端
# settings.py
AUTHENTICATION_BACKENDS = [
'accounts.auth_backends.EmailOrPhoneBackend',
'django.contrib.auth.backends.ModelBackend',
]
七、实用工具函数
# accounts/utils.py
from django.contrib.auth import get_user_model
from django.contrib.auth.tokens import default_token_generator
from django.core.mail import send_mail
from django.template.loader import render_to_string
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode
User = get_user_model()
def send_verification_email(user, request):
"""
发送邮箱验证邮件
"""
token = default_token_generator.make_token(user)
uid = urlsafe_base64_encode(force_bytes(user.pk))
verification_url = request.build_absolute_uri(
f'/accounts/verify/{uid}/{token}/'
)
context = {
'user': user,
'verification_url': verification_url,
}
message = render_to_string('accounts/email/verification.html', context)
send_mail(
'验证您的邮箱',
message,
'noreply@example.com',
[user.email],
html_message=message,
)
def get_user_permissions(user):
"""
获取用户所有权限(包括组权限)
"""
if user.is_superuser:
return User.objects.all().values_list('auth.permission__codename', flat=True)
return user.user_permissions.values_list('codename', flat=True) | \
user.groups.values_list('permissions__codename', flat=True).distinct()
八、最佳实践建议
-
密码安全
- 使用强密码策略
- 实现密码过期机制
- 记录密码修改历史
-
会话管理
- 设置合适的会话超时时间
- 实现"记住我"功能
- 多设备登录控制
-
权限设计
- 最小权限原则
- 合理分组
- 定期审核权限
-
安全防护
- 实现登录尝试限制
- 启用CSRF保护
- 实现双因素认证
九、练习任务
-
实现一个完整的用户认证系统,包含:
- 用户注册(带邮箱验证)
- 登录(支持用户名/邮箱/手机号)
- 找回密码
- 修改个人信息
-
创建一个权限管理系统:
- 自定义权限
- 用户组管理
- 权限分配界面
-
实现高级功能:
- OAuth 2.0集成
- JWT认证
- API认证
十、总结
今天我们学习了Django认证系统的核心组件:
- 用户认证基础知识
- 权限系统的实现和使用
- 用户组管理
- 自定义认证系统
怎么样今天的内容还满意吗?再次感谢朋友们的观看,关注GZH:凡人的AI工具箱,回复666,送您价值199的AI大礼包。最后,祝您早日实现财务自由,还请给个赞,谢谢!