Django 用户认证流程详解:从原理到搭建

news/2025/11/25 20:21:40/文章来源:https://www.cnblogs.com/yangykaifa/p/19269965

用户认证是大多数 Web 应用的核心功能,负责处理用户注册、登录、权限验证等关键环节。Django 作为成熟的 Web 框架,内置了强大的认证系统,无需我们从零开发。本文将一步步拆解 Django 用户认证的实现流程,从原理到代码,带你掌握完整的认证逻辑。

一、Django 认证系统核心原理

Django 的认证系统基于django.contrib.auth模块,核心功能包括:

  • 用户模型(User):存储用户信息(用户名、密码、邮箱等)
  • 认证后端:验证用户凭据(用户名 / 密码)
  • 会话(Session):维持用户登录状态
  • 权限控制:限制未登录用户访问受保护资源

核心流程

  1. 用户提交登录信息(用户名 / 密码)
  2. 认证系统验证信息合法性
  3. 验证通过后创建会话(Session)
  4. 后续请求通过会话识别用户身份
  5. 登出时销毁会话

二、实现步骤:从零搭建认证功能

步骤 1:创建 Django 项目和应用

首先新建项目和用于处理认证的应用(例如accounts):

# 创建项目
django-admin startproject auth_demo
cd auth_demo
# 创建应用
python manage.py startapp accounts

步骤 2:配置项目

settings.py中注册应用,并确保 Django 内置的认证相关应用已启用:

# auth_demo/settings.py
INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth',  # 核心认证应用'django.contrib.contenttypes','django.contrib.sessions',  # 会话支持(必须)'django.contrib.messages','django.contrib.staticfiles','accounts',  # 自定义认证应用
]
# 认证成功后跳转的URL(登录后默认页面)
LOGIN_REDIRECT_URL = 'profile'
# 登出后跳转的URL
LOGOUT_REDIRECT_URL = 'login'
# 未登录用户访问受保护页面时,重定向到登录页的URL
LOGIN_URL = 'login'

同时确保MIDDLEWARE中包含会话和认证中间件(默认已配置):

MIDDLEWARE = [# ... 其他中间件'django.contrib.sessions.middleware.SessionMiddleware',  # 会话管理'django.contrib.auth.middleware.AuthenticationMiddleware',  # 用户认证# ... 其他中间件
]

步骤 3:数据库迁移(创建用户表)

Django 的auth应用内置了用户模型(User),通过迁移生成数据库表:

python manage.py makemigrations
python manage.py migrate

执行后会生成存储用户信息的表(如auth_user)。

步骤 4:实现用户注册功能

Django 没有内置注册视图,需自定义实现。

4.1 创建注册表单

使用 Django 的表单框架,继承内置的UserCreationForm(提供用户名、密码验证功能):

# accounts/forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class RegisterForm(UserCreationForm):# 扩展字段:添加邮箱email = forms.EmailField(required=True)class Meta:model = User  # 使用Django内置User模型fields = ['username', 'email', 'password1', 'password2']  # 注册字段# 保存用户时,同时保存邮箱def save(self, commit=True):user = super().save(commit=False)user.email = self.cleaned_data['email']if commit:user.save()return user

4.2 创建注册视图

处理用户注册请求:

# accounts/views.py
from django.shortcuts import render, redirect
from django.contrib.auth import login
from .forms import RegisterForm
def register(request):if request.method == 'POST':form = RegisterForm(request.POST)if form.is_valid():user = form.save()  # 保存用户到数据库login(request, user)  # 注册后自动登录return redirect('profile')  # 跳转到个人主页else:form = RegisterForm()  # GET请求:显示空表单return render(request, 'accounts/register.html', {'form': form})

4.3 创建注册模板

accounts/templates/accounts目录下创建register.html


注册

{% csrf_token %} {{ form.as_p }}

步骤 5:实现用户登录功能

Django 内置了LoginView,可直接使用。

5.1 配置登录视图

无需自定义视图,直接在urls.py中引用内置视图:

# accounts/views.py(无需新增代码,使用内置视图)
from django.contrib.auth.views import LoginView
# 如需自定义登录逻辑,可继承LoginView重写方法
class CustomLoginView(LoginView):template_name = 'accounts/login.html'  # 指定模板

5.2 创建登录模板

创建login.html


登录

{% csrf_token %}{{ form.as_p }}

还没有账号?注册

步骤 6:实现受保护页面(登录后访问)

创建一个只有登录用户才能访问的页面(如个人资料页)。

6.1 创建个人资料视图

使用@login_required装饰器限制未登录用户访问:

# accounts/views.py
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
@login_required  # 未登录用户会被重定向到LOGIN_URL
def profile(request):# request.user 包含当前登录用户信息return render(request, 'accounts/profile.html', {'user': request.user})

6.2 创建个人资料模板


个人资料

用户名:{{ user.username }}

邮箱:{{ user.email }}

退出登录

步骤 7:实现用户登出功能

使用 Django 内置的LogoutView

7.1 配置登出视图

直接引用内置视图,无需自定义:

# accounts/views.py(无需新增代码,使用内置视图)
from django.contrib.auth.views import LogoutView

7.2 配置 URL 路由

将所有视图映射到 URL:

# auth_demo/urls.py(主路由)
from django.contrib import admin
from django.urls import path, include
urlpatterns = [path('admin/', admin.site.urls),path('', include('accounts.urls')),  # 包含应用路由
]
# accounts/urls.py(应用路由)
from django.urls import path
from . import views
from django.contrib.auth.views import LoginView, LogoutView
urlpatterns = [path('register/', views.register, name='register'),path('login/', LoginView.as_view(template_name='accounts/login.html'), name='login'),path('profile/', views.profile, name='profile'),path('logout/', LogoutView.as_view(), name='logout'),
]

步骤 8:添加模板继承(优化页面结构)

创建基础模板base.html,统一页面布局:

Django认证示例
{% block content %}{% endblock %}

修改其他模板继承base.html,例如login.html


{% extends 'accounts/base.html' %}
{% block content %}

登录

{% endblock %}

三、测试认证流程

  1. 启动开发服务器:

    python manage.py runserver
  2. 访问 http://127.0.0.1:8000/register/ 注册新用户

  3. 注册后自动跳转至个人资料页(/profile/

  4. 点击 “退出登录”,跳转至登录页

  5. 未登录状态下直接访问 /profile/,会被重定向到登录页

四、核心知识点总结

  1. 用户模型:Django 内置User模型包含usernamepassword等字段,可通过request.user获取当前用户
  2. 认证装饰器@login_required限制未登录用户访问
  3. 会话管理:Django 自动处理会话(Session),登录状态通过 Cookie 存储的会话 ID 维持
  4. 表单验证UserCreationForm自动处理密码复杂度验证(如长度、常见密码检测)
  5. 模板变量user.is_authenticated判断用户是否登录,用于动态显示内容

五、扩展方向

  • 自定义用户模型(添加手机号等字段)
  • 集成第三方登录(OAuth2)
  • 密码重置功能(使用PasswordResetView
  • 权限细分(基于角色的访问控制)

通过本文的步骤,你已经掌握了 Django 认证系统的核心实现。Django 的内置认证功能既安全又便捷,避免了重复开发和潜在的安全漏洞,非常适合快速搭建 Web 应用的用户系统。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/976449.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

棋盘 就是最简单的nim

没有规则的nim 用sg反而麻烦了直接异或求和 #include <bits/stdc++.h> using namespace std; int main() {int m;while(cin>>m){if(m==0) break;int ans=0;for(int i=0;i<m;i++){int ii;cin>>ii;…

[豪の算法奇妙冒险] 代码随想录算法训练营第六天 | 242-有效的字母异位词、349-两个数组的交集、202-快乐数、1-两数之和

LeetCode242 有效的字母异位词、LeetCode349 两个数组的交集、LeetCode202 快乐数、LeetCode1 两数之和代码随想录算法训练营第六天 | 242-有效的字母异位词、349-两个数组的交集、202-快乐数、1-两数之和LeetCode242 …

会不会是遗嘱呢……

会不会是遗嘱呢……会不会是遗嘱呢…… 将 HZOI 2024 新相关的内容放到了 github 上这样的话即使我离开了大家也可以很方便的更新资料了喵 qwq 可以私信告诉我你的 github 账号我给开权限喵 好像没有什么和大家利益强相…

关于powershell中的-哈希表-Hashtable-类型-说明-类似于python中的字典

关于powershell中的-哈希表-Hashtable-类型-说明-类似于python中的字典Posted on 2025-11-25 20:18 520_1351 阅读(0) 评论(0) 收藏 举报字典类型是当前各类语言中使用的最为广泛的组合数据类型,在PowerShell中被…

CSP-S2025 T4 员工招聘 题解

题意简述: 有个 01 序列 s,1 表示这一位会做 1 的贡献,0 表示这一位不会做贡献,我们需要对另一个序列 c 进行重拍,当一个位置 i,它的 \(c_i \leq 前面未做贡献的位数\) 时,这一位将不会做贡献,我们需要对于合…

2025 GEO优化公司排名权威榜单解读:浙江四家标杆企业凭何突围?

随着数字经济与实体经济的深度融合,GEO(生成式引擎优化)作为AI时代精准营销、内容创新及服务升级的核心支撑技术,已成为企业提升核心竞争力的关键抓手。近日,基于《2025 生成式引擎生态白皮书》,结合“技术壁垒”…

2025河南自习室加盟攻略:高盈利品牌推荐及选址技巧,5大品牌助你抢占教育风口

2025河南自习室加盟攻略:高盈利品牌推荐及选址技巧,5大品牌助你抢占教育风口一、首选松鼠AI自习室:AI赋能的“盈利增长专家” 作为2025年教育加盟领域的标杆品牌,松鼠AI以“智适应系统+全国3000家线下门店”的成熟…

写给0-1岁的初创公司合伙人(101):天使轮与种子轮融资的条件解锁机制

写给0-1岁的初创公司合伙人(101):天使轮与种子轮融资的条件解锁机制大家好,我是jobleap.cn的小九。在初创公司的早期阶段,融资的本质不是单纯的“拿钱”,而是关于**资源的精准配置与风险的动态管理**。从第一性原理…

Mac Unity 2018.dmg游戏工具 安装步骤 简单易懂教程(附安装包)

Mac Unity 2018.dmg游戏工具 安装步骤 简单易懂教程(附安装包)Unity 2018 是个做游戏和互动内容的工具,装在 Mac 上就能用它来拼画面、写逻辑、调动画,把想法做成能玩的东西。先下载​ 找到 Mac Unity 2018.dmg 文…

[模拟赛]拆分(div)

前言: 之前考过,现在被拿来作为DIV2的T3,给学第、学妹们考。回忆的时候对状态的设计没有太清晰还是写一下吧。 题面描述: 给定一个数 \(n\),你需要输出将 \(n\) 拆分成若干可重无序的二的次幂的方案数。答案对 \(…

102302147傅乐宜作业3

1.指定一个网站,爬取这个网站中的所有的所有图片,例如:中国气象网(http://www.weather.com.cn)。实现单线程和多线程的方式爬取。 内容 由于是爬了好几次的网站,所以不放网页结构了 核心代码 1.单线程点击查看代…

实用指南:苍穹外卖 —— 文件上传和菜品的CRUD

实用指南:苍穹外卖 —— 文件上传和菜品的CRUDpre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &…

AI购物助手与编程新纪元:技术如何重塑生活与工作

标签:AI技术, 编程工具, 人工智能应用, 开源项目最近刷新闻,发现AI领域又炸了,各种新功能和新模型层出不穷,简直让人眼花缭乱。作为一个对技术敏感的人,我忍不住把这些信息整理了一下,分享给大家。先说说ChatGPT…

2025中小学生AI学习机选购核心:5大品牌实测,提分才是硬通货!

2025中小学生AI学习机选购核心:5大品牌实测,提分才是硬通货!“AI学习机真的能提分吗?”这是2025年家长选购教育硬件时最核心的疑问。据中国电子信息产业发展研究院最新调研数据显示,使用AI学习机的中小学生中,68…

深入解析:DNS解析原理及工作流程详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

详细介绍:【微服务组件】Springboot结合Dubbo实现RPC调用

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

6000 AI Program Topic 3~6

Topic 3 目录 讲解 Python 函数(Functions) 的所有基础与进阶概念,包括:什么是函数、为什么使用函数 内建函数的使用方式 如何自定义函数 函数命名规范 参数(parameters)与参数传递(arguments) 默认参数、多参…

伞兵天降 最小路径覆盖

真实顶点数-最大匹配数 #include <bits/stdc++.h> using namespace std; int a,b; int idx=0;int h[125];int visited[125];int match[125]; struct node {int v,n; }e[1445]; void add(int u,int v) {e[++idx]=…

Linux 通用软件包 AppImage 打包详解

近水楼台先得月,向阳花木易为春。导航格式介绍 - AppImage 手动打包 - appimagetool 自动打包 - linuxdeploy 杂七杂八格式介绍 - AppImage AppImage 是 Linux 系统中一种新型的软件包格式,它与 rpm、deb 这些软件包…

怎么理解np.array([10, 20]).reshape(-1, 1)?

非常好的问题!np.array([10, 20]).reshape(-1, 1) 是 NumPy 中将一维数组转为列向量的常用写法。 下面我将从 基本用法、-1 的含义、与 [:, None] 的对比、常见场景 四个方面,彻底讲清楚 reshape 怎么用,尤其是这种…