第七章 Django用户认证与会话技术

第一章 Django 基本使用

第二章 Django URL路由系统

第三章 Django 视图系统

第四章 Django 模板系统

第五章 Django 数据模型系统(基本使用)

第六章 Django 数据模型系统(多表操作)

第七章 Django 用户认证与会话技术

第八章 Django CSRF防护


文章目录


内置用户认证系统

介绍

Django内置的用户认证系统基于auth模块实现

auth模块提供了登录、注册、校检、修改密码、注销、验证用户是否登录等功能。

主要包括以下几个部分:

  • 用户模型(User Model):Django提供了一个默认的用户模型,可以根据需要自定义字段。要使用这个模型,需要在settings.py中设置AUTH_USER_MODEL'auth.User'
  • 认证后端(Authentication Backends):Django支持多种认证后端,如数据库、LDAP等。要使用某个认证后端,需要在settings.py中设置AUTHENTICATION_BACKENDS
  • 视图和URL配置:Django提供了一些视图和URL模式来处理用户认证相关的请求,如登录、注册、密码重置等。需要在urls.py中添加相应的URL模式
  • 模板和表单:Django提供了一些模板和表单用于显示认证相关的页面,如登录、注册等。可以在模板中使用这些表单
    登录 退出 用户信息认证 登录认证装饰器 获取登录用户信息 扩展auth_user表字段 auth login logout authenticate decorators login_required models user BaseUserManage,AbstractBaseUser

Django默认创建的数据库表包括

  1. auth_user:用户表,用于存储用户的身份验证信息。

  2. auth_user_groups:用户所属组的表,用于存储用户与用户组之间的关系。

  3. auth_user_user_permissions:用户权限表,用于存储用户的权限信息。

  4. auth_group:用户组表,用于存储用户组的信息。

  5. auth_group_permissions:用户组权限表,用于存储用户组的权限信息。

  6. auth_permission:存放全部权限的表,其他的表的权限都是从此表中外键连接过去的。

  7. django_session:保存HTTP状态的表。

  8. django_migrations:数据库迁移记录的表

auth模块使用

login&logout

准备工作

http://49.232.221.200:8080/admin/auth/user/

路由

python 复制代码
# myorm/urls.py
from django.urls import include, path, re_path
from myorm import views
from .views import view_course_students,edit_student,drop_student
urlpatterns = [
    path('login/', views.login, name='login'),
    path('home_page/', views.home_page, name='home_page'),
    path('logout/', views.logout, name='logout'),
]

视图

python 复制代码
# myorm/views.py
from django.shortcuts import render, get_object_or_404,redirect,HttpResponse
from .models import Course, Student
from django.contrib import auth    


def login(request):
    if request.method == "GET":
        return render(request, "login.html")
    elif request.method == "POST":
        username = request.POST.get("username",None)
        password = request.POST.get("password",None)
        # 对用户数据验证
        user = auth.authenticate(username=username, password=password)
        # 如果效验成功,返回一个用户对象,否则返回一个None
        if user:
            # 验证通过后,将request与用户对象(包含session)传给login()函数
            auth.login(request, user)
            # 跳转到http://49.232.221.200:8080/myorm/home_page
            return redirect("home_page")
        else:
            mag = '用户名密码错误'
        return render(request, "login.html",{'mag': mag})

def home_page(request):
    return render(request,"home_page.html")

def logout(request):
    # 清除当前用户的session信息
    auth.logout(request)
    return redirect('login')

网页

html 复制代码
<!-- myrom/templates/login.html -->
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>登录</title>
    </head>
    <body>
        <form action="" method="post">
            <h1>登录</h1>
            用户名:<input type="text" name="username"><br>
            密码:<input type="text" name="password"><br>
            <button type="submit">登录</button>
        </form><br>
        <span style="color: red;">{{ mag }}</span>
    </body>
</html>
html 复制代码
<!-- myrom/templates/home_page.html -->
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>标题</title>
    </head>
    <body>
        
        <h1>欢迎访问首页</h1>
        <a href="/myorm/logout">退出</a>
    </body>
</html>

验证

登录成功会有一个session的会话记录,退出后就没有了

http://49.232.221.200:8080/myorm/login/

登录认证装饰器

login_required装饰器通常用于Django框架中,用于确保用户在访问某个视图函数之前已经登录。当用户未登录时,他们将被重定向到登录页面

路由

python 复制代码
# myorm/urls.py
from django.urls import include, path, re_path
from myorm import views
from .views import view_course_students,edit_student,drop_student
urlpatterns = [
    path('login/', views.login, name='login'),
    path('home_page/', views.home_page, name='home_page'),
    path('logout/', views.logout, name='logout'),
]

视图

python 复制代码
# myorm/views.py
from django.shortcuts import render, get_object_or_404,redirect,HttpResponse
from .models import Course, Student
from django.contrib import auth
from django.contrib.auth.decorators import login_required


def login(request):
    if request.method == "GET":
        return render(request, "login.html")
    elif request.method == "POST":
        username = request.POST.get("username",None)
        password = request.POST.get("password",None)
        # 对用户数据验证
        user = auth.authenticate(username=username, password=password)
        # 如果效验成功,返回一个用户对象,否则返回一个None
        if user:
            # 验证通过后,将request与用户对象(包含session)传给login()函数
            auth.login(request, user)
            # 跳转到http://49.232.221.200:8080/myorm/home_page
            return redirect("home_page")
        else:
            mag = '用户名密码错误'
        return render(request, "login.html",{'mag': mag})
# 加入这个配置
@login_required()
def home_page(request):
    return render(request,"home_page.html")

def logout(request):
    # 清除当前用户的session信息
    auth.logout(request)
    return redirect('login')

网页

html 复制代码
<!-- myrom/templates/login.html -->
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>登录</title>
    </head>
    <body>
        <form action="" method="post">
            <h1>登录</h1>
            用户名:<input type="text" name="username"><br>
            密码:<input type="text" name="password"><br>
            <button type="submit">登录</button>
        </form><br>
        <span style="color: red;">{{ mag }}</span>
    </body>
</html>
html 复制代码
<!-- myrom/templates/home_page.html -->
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>标题</title>
    </head>
    <body>
        
        <h1>欢迎访问首页</h1>
        <a href="/myorm/logout">退出</a>
    </body>
</html>

验证

没有加入@login_required()时候可以直接访问

http://49.232.221.200:8080/myorm/home_page/

加入@login_required()

没有登录的话,访问是直接报错的

解决报错

python 复制代码
# orm/setting.py
# 在settings.py最下边文件设置没有登录默认跳转页面:
LOGIN_URL = '/myorm/login'

访问http://49.232.221.200:8080/myorm/home_page/跳转到了登录界面

Session管理

Session与Cookie是什么

Cookie和Session都是Web程序中跟踪用户会话的关键技术。它们都使得HTTP协议具备了状态,能记录和跟踪用户的整个会话过程。

Cookie是存储在客户端的一种数据结构,形如"name=value"的变量。它是服务器发送到用户浏览器并保存在浏览器上的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,Cookie用来跟踪会话,也可以保存用户的喜好或者保存用户名密码等信息。

Session则是存储在服务器端的一种数据结构,通常是一个映射(键值对)。当用户访问服务器时,服务器会为该用户创建一个session对象,用于存储该用户的信息。这个session对象包含了所有需要记录用户状态的信息,比如用户的登录状态、用户的名称等等。一个sessionID会被保存在客户端的Cookie中,这样当浏览器再次访问服务器时,服务器就能通过读取Cookie中的sessionID来识别用户。

总结来说,Cookie和Session都是为了在客户端与服务器之间保持会话所需要的一种技术。两者的主要区别在于:Cookie将信息保存在客户端,而Session则将信息保存在服务器端。

举例

假设你在使用一个网站,首先你需要输入用户名和密码进行登录。此时,你的浏览器会向服务器发送一个包含这些信息的POST请求。服务器接收到请求后,会在响应头中添加一条"set-cookie: JSESSIONID"字段,这条信息是用于记录你的用户信息。同时,服务器还会创建一个session对象来保存你的登录状态等信息。

随后,服务器会把包含Session信息的Cookie发回给你的浏览器。你的浏览器接收到这个Cookie后,会将其保存在磁盘上。这意味着,下次你再次访问服务器时,浏览器会自动携带这个Cookie信息。服务器通过读取这个Cookie中的SessionID来识别你,并获取你的登录状态等信息。

这样,客户端和服务端就实现了会话跟踪。无论是点击多个超链接还是关闭再重新打开浏览器,只要SessionID未过期或被清除,你的登录状态都能得到保持。
会话管理 Cookie 数据存储再浏览器端 特点 方便与js交换数据 方便获取用户信息 风险 浏览器可能会禁用Cookie Session 数据存储在服务端 特点 高效 安全 不依赖浏览器环境 服务器端会为每一个用户分配一个ID标识

使用Session

在settings.py配置文件中设置客户端Cookie:

参数 描述
SESSION_COOKIE_NAME = "sessionid" Session的cookie保存在浏览器上时的key 即:sessionid=随机字符串(默认)
SESSION_COOKIE_PATH = "/" Session的cookie保存的路径(默认)
SESSION_COOKIE_DOMAIN = None Session的cookie保存的域名(默认)
SESSION_COOKIE_SECURE = False 是否Https传输cookie(默认)
SESSION_COOKIE_HTTPONLY = True 是否Session的cookie只支持http传输(默认)
SESSION_COOKIE_AGE = 1209600 Session的cookie失效日期(2周)(默认)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False 是否关闭浏览器使得Session过期(默认)
SESSION_SAVE_EVERY_REQUEST = False 是否每次请求都保存Session,默认修改之后才保存(默认)

在视图中操作Session:

参数 描述
request.session['key'] = value 向Session写入键值
request.session.get('key',None) 获取Session中键的值
request.session.flush() 清除Session数据
request.session.set_expiry(value) Session过期时间

示例

python 复制代码
# orm/setting.py
# 最下边添加
# 调整过期时间为60秒
SESSION_COOKIE_AGE = 60

写个登录案例

准备工作

user表增加一个字段

python 复制代码
# myorm/models.py
from django.db import models

# Create your models here.
# 定义一个用户表,继承model类
class User(models.Model):
    user = models.CharField(max_length=30) # 定义user字段,并定义为字符串以及设置长度
    name = models.CharField(max_length=30) # 定义name字段,并定义为字符串以及设置长度
    sex = models.CharField(max_length=10) # 定义sex字段,并定义为字符串以及设置长度
    age = models.IntegerField() # 定义age字段,并定义为整型
    label = models.CharField(max_length=100) # 定义label字段,并定义为字符串以及设置长度
    password = models.CharField(max_length=100, default='123456',verbose_name="密码")  # 增加的字段,默认是123456
    
    class Meta:
        app_label = "myorm" # 指定APP名称
        db_table = 'user'   # 自定义生成的表名
        managed = True     # Django自动管理数据库表
        verbose_name = '用户表'  # 对象的可读名称
        verbose_name_plural = '用户表'  # 名称复数形式
        ordering = ["sex"] # 对象的默认顺序,用于获取对象列表时

    def __str__(self):
        return self.name
bash 复制代码
python3 manage.py makemigrations
python3 manage.py migrate

路由

python 复制代码
# myorm/urls.py
from django.urls import include, path, re_path
from myorm import views
urlpatterns = [
    path('login/', views.login, name='login'),
    path('home_page/', views.home_page, name='home_page'),
    path('logout/', views.logout, name='logout'),
]

视图

python 复制代码
# myorm/views.py
from django.shortcuts import render, get_object_or_404,redirect,HttpResponse
from .models import Course, Student
from django.contrib import auth
from django.contrib.auth.decorators import login_required


# 定义一个装饰器
def self_login_required(func):
    def inner(request):
        is_login = request.session.get('is_login', False)
        if not is_login:
            return redirect(login)
        else:
            return func(request)
    return inner

@self_login_required
def home_page(request):
    return render(request,"home_page.html")

def login(request):
    if request.method == "GET":
        return render(request, "login.html")
    elif request.method == "POST":
        username = request.POST.get("username",None)
        password = request.POST.get("password",None)
        # 对用户数据验证
        user = User.objects.filter(user=username)
        if user:
            for i in user:
                passwd = i.password
            if password == passwd:
                # 验证通过后,将request与用户对象(包含session)传给login()函数
                request.session['is_login'] =True
                request.session['username'] = username
                # 跳转到http://49.232.221.200:8080/myorm/home_page
                return redirect("home_page")
            else:
                mag = '用户名密码错误'
        else:
            mag = '用户名密码错误'
        return render(request, "login.html",{'mag': mag})

def logout(request):
    # 清除当前用户的session信息
    auth.logout(request)
    return redirect('login')

网页

html 复制代码
<!-- myrom/templates/login.html -->
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>登录</title>
    </head>
    <body>
        <form action="" method="post">
            <h1>登录</h1>
            用户名:<input type="text" name="username"><br>
            密码:<input type="text" name="password"><br>
            <button type="submit">登录</button>
        </form><br>
        <span style="color: red;">{{ mag }}</span>
    </body>
</html>
html 复制代码
<!-- myrom/templates/home_page.html -->
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>标题</title>
    </head>
    <body>
        
        <h1>欢迎访问首页</h1>
        <a href="/myorm/logout">退出</a>
    </body>
</html>

验证

http://49.232.221.200:8080/myorm/login/

账户名密码就是user表中的数据

退出后没有session的记录了

@self_login_required
def home_page(request):

上加了装饰器,那么无法直接访问http://49.232.221.200:8080/myorm/home_page/,需要登录在进行访问

相关推荐
萧鼎1 小时前
Python并发编程库:Asyncio的异步编程实战
开发语言·数据库·python·异步
学地理的小胖砸1 小时前
【一些关于Python的信息和帮助】
开发语言·python
疯一样的码农1 小时前
Python 继承、多态、封装、抽象
开发语言·python
Wx-bishekaifayuan1 小时前
django电商易购系统-计算机设计毕业源码61059
java·spring boot·spring·spring cloud·django·sqlite·guava
Python大数据分析@2 小时前
python操作CSV和excel,如何来做?
开发语言·python·excel
黑叶白树2 小时前
简单的签到程序 python笔记
笔记·python
Shy9604182 小时前
Bert完形填空
python·深度学习·bert
上海_彭彭2 小时前
【提效工具开发】Python功能模块执行和 SQL 执行 需求整理
开发语言·python·sql·测试工具·element
zhongcx012 小时前
使用Python查找大文件的实用脚本
python
yyfhq3 小时前
sdnet
python