尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Django认证系统详解:从用户模型到权限管理
1. Django认证系统概述Django认证系统是Django框架内置的一套完整的用户认证解决方案它提供了用户账号、会话、权限和用户组等核心功能。这套系统开箱即用能够满足大多数Web应用的用户管理需求。作为一个全栈开发者我使用Django认证系统已经有7年时间从简单的博客系统到复杂的企业级应用都有实践。认证系统最让我欣赏的是它的约定优于配置理念 - 你不需要从零开始造轮子但又可以灵活地定制几乎每个环节。认证系统的核心组件包括用户模型(User)存储用户凭证和个人信息权限(Permissions)控制用户能做什么用户组(Groups)批量分配权限的方式可配置的密码哈希系统表单和视图处理登录/注销等标准操作可插拔的后端系统2. 用户模型深度解析2.1 内置User模型Django默认使用django.contrib.auth.models.User模型它包含以下核心字段username必填30字符以内唯一password必填存储的是哈希值而非明文email可选first_name/last_name可选is_active布尔值表示账号是否激活is_staff布尔值表示是否可以访问admin站点is_superuser布尔值表示拥有所有权限last_login记录最后登录时间date_joined账号创建时间在项目中引用User模型的最佳实践是使用django.contrib.auth.get_user_model()这样即使你后来自定义了用户模型代码也不需要修改。2.2 自定义用户模型虽然内置User模型能满足基本需求但实际项目中我们经常需要扩展用户信息。Django推荐的方式是从AbstractUser或AbstractBaseUser继承创建自定义模型。from django.contrib.auth.models import AbstractUser class CustomUser(AbstractUser): age models.PositiveIntegerField(nullTrue, blankTrue) bio models.TextField(max_length500, blankTrue) avatar models.ImageField(upload_toavatars/, nullTrue, blankTrue) class Meta: verbose_name 用户 verbose_name_plural 用户关键点必须在第一次migrate前定义自定义用户模型需要在settings.py中设置AUTH_USER_MODELAUTH_USER_MODEL myapp.CustomUser所有引用User模型的地方都要改为get_user_model()或settings.AUTH_USER_MODEL2.3 密码处理机制Django不会存储原始密码而是存储密码的哈希值。密码处理流程用户注册/修改密码时前端通过表单提交原始密码Django使用PBKDF2算法默认加随机salt生成哈希哈希值被存储到数据库密码验证流程用户登录时提交密码Django使用相同算法和存储的salt重新计算哈希比较计算出的哈希和存储的哈希安全建议永远不要直接存储明文密码使用make_password()函数创建密码哈希使用check_password()验证密码考虑使用更安全的哈希算法如Argon2Django 3.0支持3. 权限系统详解3.1 默认权限Django自动为每个模型创建4种基本权限add添加该模型的实例change修改该模型的实例delete删除该模型的实例view查看该模型的实例Django 2.1这些权限格式为app_label.action_model_name例如blog.add_post添加博客文章blog.change_post修改博客文章blog.delete_post删除博客文章blog.view_post查看博客文章3.2 自定义权限可以在模型的Meta类中定义额外权限class Post(models.Model): title models.CharField(max_length100) content models.TextField() class Meta: permissions [ (can_publish, 可以发布文章), (can_audit, 可以审核文章), ]3.3 权限检查在视图和模板中检查权限# 视图中检查权限 if request.user.has_perm(blog.can_publish): # 有权限的逻辑 else: # 无权限的逻辑 # 模板中检查权限 {% if perms.blog.can_publish %} !-- 有权限显示的内容 -- {% endif %}3.4 用户组用户组是批量管理权限的有效方式from django.contrib.auth.models import Group, Permission # 创建编辑组并分配权限 editors Group.objects.create(name编辑) can_publish Permission.objects.get(codenamecan_publish) editors.permissions.add(can_publish) # 将用户加入组 user.groups.add(editors) # 检查用户是否在组中 if user.groups.filter(name编辑).exists(): # 用户是编辑组成员4. 认证视图与表单4.1 内置认证视图Django提供了一组开箱即用的认证视图处理常见场景from django.contrib.auth import views as auth_views urlpatterns [ path(login/, auth_views.LoginView.as_view(), namelogin), path(logout/, auth_views.LogoutView.as_view(), namelogout), path(password_change/, auth_views.PasswordChangeView.as_view(), namepassword_change), path(password_change/done/, auth_views.PasswordChangeDoneView.as_view(), namepassword_change_done), path(password_reset/, auth_views.PasswordResetView.as_view(), namepassword_reset), path(password_reset/done/, auth_views.PasswordResetDoneView.as_view(), namepassword_reset_done), path(reset/uidb64/token/, auth_views.PasswordResetConfirmView.as_view(), namepassword_reset_confirm), path(reset/done/, auth_views.PasswordResetCompleteView.as_view(), namepassword_reset_complete), ]4.2 登录视图定制LoginView是最常用的认证视图之一可以灵活定制class CustomLoginView(auth_views.LoginView): template_name accounts/custom_login.html redirect_authenticated_user True # 已登录用户访问登录页将重定向 authentication_form CustomAuthenticationForm # 自定义表单 def form_valid(self, form): # 添加自定义逻辑 remember_me form.cleaned_data.get(remember_me) if remember_me: self.request.session.set_expiry(30 * 24 * 60 * 60) # 30天 else: self.request.session.set_expiry(0) return super().form_valid(form)4.3 认证表单Django提供了多种认证相关的表单AuthenticationForm处理用户登录UserCreationForm新用户注册PasswordChangeForm修改密码PasswordResetForm重置密码请求SetPasswordForm设置新密码自定义表单示例from django.contrib.auth.forms import AuthenticationForm class CustomAuthenticationForm(AuthenticationForm): remember_me forms.BooleanField( requiredFalse, initialTrue, label记住我 ) def confirm_login_allowed(self, user): super().confirm_login_allowed(user) if not user.is_email_verified: # 自定义检查 raise forms.ValidationError( 请先验证您的邮箱地址, codeemail_not_verified, )5. 认证后端与高级配置5.1 认证后端Django支持多种认证后端默认使用ModelBackend。可以配置多个后端Django会按顺序尝试认证AUTHENTICATION_BACKENDS [ django.contrib.auth.backends.ModelBackend, # 默认 myapp.backends.EmailBackend, # 自定义后端 ]自定义认证后端示例from django.contrib.auth.backends import BaseBackend from django.contrib.auth import get_user_model class EmailBackend(BaseBackend): def authenticate(self, request, emailNone, passwordNone, **kwargs): UserModel get_user_model() try: user UserModel.objects.get(emailemail) if user.check_password(password): return user except UserModel.DoesNotExist: return None def get_user(self, user_id): UserModel get_user_model() try: return UserModel.objects.get(pkuser_id) except UserModel.DoesNotExist: return None5.2 会话管理Django使用会话来跟踪用户的认证状态。重要设置# settings.py SESSION_COOKIE_AGE 1209600 # 2周默认 SESSION_COOKIE_SECURE True # 仅HTTPS SESSION_COOKIE_HTTPONLY True # 防止JavaScript访问 SESSION_EXPIRE_AT_BROWSER_CLOSE False # 持久会话密码修改后使现有会话失效from django.contrib.auth import update_session_auth_hash def password_change_view(request): if request.method POST: form PasswordChangeForm(userrequest.user, datarequest.POST) if form.is_valid(): form.save() # 更新会话哈希防止用户被登出 update_session_auth_hash(request, form.user) return redirect(home) else: form PasswordChangeForm(userrequest.user) return render(request, password_change.html, {form: form})5.3 安全配置# settings.py # 密码验证器 AUTH_PASSWORD_VALIDATORS [ { NAME: django.contrib.auth.password_validation.UserAttributeSimilarityValidator, }, { NAME: django.contrib.auth.password_validation.MinimumLengthValidator, OPTIONS: { min_length: 8, } }, { NAME: django.contrib.auth.password_validation.CommonPasswordValidator, }, { NAME: django.contrib.auth.password_validation.NumericPasswordValidator, }, ] # 登录URL LOGIN_URL /accounts/login/ # 登录后重定向 LOGIN_REDIRECT_URL /dashboard/ # 登出后重定向 LOGOUT_REDIRECT_URL /6. 实战技巧与常见问题6.1 用户注册流程完整的用户注册流程通常包括注册表单收集信息发送验证邮件用户点击验证链接激活账号完成注册示例代码from django.contrib.auth import get_user_model from django.core.mail import send_mail from django.template.loader import render_to_string from django.utils.http import urlsafe_base64_encode from django.utils.encoding import force_bytes from django.contrib.auth.tokens import default_token_generator def register(request): if request.method POST: form UserRegistrationForm(request.POST) if form.is_valid(): user form.save(commitFalse) user.is_active False # 先不激活 user.save() # 发送激活邮件 mail_subject 激活您的账号 message render_to_string(acc_active_email.html, { user: user, domain: request.get_host(), uid: urlsafe_base64_encode(force_bytes(user.pk)), token: default_token_generator.make_token(user), }) send_mail(mail_subject, message, noreplyexample.com, [user.email]) return redirect(registration_pending) else: form UserRegistrationForm() return render(request, register.html, {form: form}) def activate(request, uidb64, token): try: uid force_str(urlsafe_base64_decode(uidb64)) user get_user_model().objects.get(pkuid) except(TypeError, ValueError, OverflowError, get_user_model().DoesNotExist): user None if user is not None and default_token_generator.check_token(user, token): user.is_active True user.save() return redirect(activation_success) else: return redirect(activation_invalid)6.2 社交账号登录集成第三方登录如Google、Facebook等可以使用Python Social Auth或allauth库。安装allauth示例pip install django-allauth配置# settings.py INSTALLED_APPS [ ... django.contrib.sites, allauth, allauth.account, allauth.socialaccount, allauth.socialaccount.providers.google, ... ] AUTHENTICATION_BACKENDS [ django.contrib.auth.backends.ModelBackend, allauth.account.auth_backends.AuthenticationBackend, ] SITE_ID 1 # 配置提供商 SOCIALACCOUNT_PROVIDERS { google: { SCOPE: [profile, email], AUTH_PARAMS: {access_type: online}, } }6.3 常见问题解决用户登录后又被重定向到登录页检查SESSION_COOKIE_DOMAIN和SESSION_COOKIE_PATH设置确保中间件顺序正确SessionMiddleware在AuthenticationMiddleware之前检查浏览器是否接受cookies密码重置邮件不发送检查EMAIL_BACKEND设置确保用户存在且is_activeTrue检查垃圾邮件文件夹使用控制台后端测试EMAIL_BACKEND django.core.mail.backends.console.EmailBackend权限不生效确保用户有权限直接分配或通过组检查权限字符串格式是否正确app_label.codename超级用户(is_superuserTrue)自动拥有所有权限自定义用户模型迁移问题确保在第一次迁移前定义AUTH_USER_MODEL如果已经创建了数据库需要先删除所有迁移和数据库然后重新迁移性能问题权限检查会产生数据库查询考虑使用缓存对于复杂的权限逻辑可以使用装饰器或中间件缓存结果7. 最佳实践总结经过多年使用Django认证系统的经验我总结了以下最佳实践项目初期就使用自定义用户模型即使开始时不需要额外字段也继承AbstractUser创建自定义模型避免后期修改用户模型的痛苦迁移过程合理设计权限系统使用组来管理角色权限为常见操作创建明确的权限避免过度依赖is_staff和is_superuser密码安全使用强密码验证器定期提醒用户更改密码考虑实现双因素认证会话安全生产环境总是使用SESSION_COOKIE_SECURE设置合理的SESSION_COOKIE_AGE提供记住我选项时延长会话时间测试认证流程测试所有认证相关视图测试边缘情况如多次错误密码尝试测试权限检查监控与日志记录重要认证事件登录成功/失败、密码修改等监控异常登录行为如异地登录实现登录尝试限制防止暴力破解保持更新及时更新Django版本以获取安全修复关注认证系统的更新日志定期审查安全设置Django认证系统虽然功能强大但要充分发挥其潜力需要深入理解其工作原理。希望本文能帮助你更好地使用这个系统构建安全可靠的用户认证功能。
RELATED

相关推荐

SageMaker生产部署六大核心问题实战指南

SageMaker生产部署六大核心问题实战指南

1. 项目概述:这不是一次简单的SageMaker教程,而是一场MLOps部署实战复盘“Deployment & Serving: Exploring 6 Key MLOps Questions using AWS SageMaker”——这个标题里藏着的不是六个待回答的理论问题,而是我在过去18个月里&#xff0…

📅 2026/8/26 4:07:05
开源项目目录的设计与实现:从分类到质量评估

开源项目目录的设计与实现:从分类到质量评估

1. 开源项目目录的价值与意义在当今技术快速迭代的时代,开源项目已经成为推动技术进步的重要力量。一个优秀的开源项目目录,就像是一座精心编排的数字图书馆,能够帮助开发者快速发现和获取有价值的开源资源。我从事开源社区工作多年&#xff…

📅 2026/8/27 3:56:22
汽油发电机逆变器智能控制系统解析与应用

汽油发电机逆变器智能控制系统解析与应用

1. 项目背景与核心功能解析INV-MCU Lab汽油变频发电机逆变器软件是一款面向工业级发电设备的智能控制系统。这套系统最核心的创新点在于将传统汽油发电机的机械调速方式升级为全数字化的变频控制方案,通过微控制器(MCU)实现频率-电压的精准闭环调节。在实际测试中&a…

📅 2026/8/27 1:59:10
MORE NEWS

更多资讯

📰

文件加密工具深度盘点:从BitLocker到age的选型与实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

以用户为中心的设计如何落地?从用户研究到可用性测试的实战指南

做体验设计这些年,我听过最矛盾的一句话,是“我们要以用户为中心,但这次版本要赶在下个月上线”。在所有设计理念里,“以用户为中心”几乎是共识度最高、却最容易被妥协的原则。它看起来像一句口号,实际上是一整套从思…

📰

ECC纠错码:从硬件校验到TypeScript类型系统的工程实践

1. ECC不是缩写,是工程实践里的一把“校验尺”ECC这个词在搜索热词里反复出现,但很多人点进去才发现——它根本不是某个具体工具、框架或产品的名字。它更像一把刻着“错误检测与纠正”字样的工程标尺,横跨硬件电路、内存芯片、存储系统、通信…

📰

Claude Code插件避坑指南:真正值得装的9款工具推荐

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

开源AI视频生成器:不是免费替代,而是可控性与流程资产化

近半年,只要点开AI视频生成相关的讨论,就能看到同一类话:某个在线平台又更新了,某个开源AI视频生成器碾压了 Seedance 2、Higgsfield AI,而且“完全无限制”。我的理解有一点不同。开源AI视频生成器和 Seedance 2、Hig…

📰

Qt XML可视化编辑:QTreeWidget与QDomDocument完整方案

简介:面向Qt开发者的XML读写与树形展示示例工程,重点演示如何将XML文件内容解析并加载到QTreeWidget中,以及将QTreeWidget节点导出保存为XML,适合需要快速落地这一场景的初学者或中级开发者使用。资源共31个文件,包含C…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬