首页 > 编程语言 >Django框架之Cookie和Session概念,Django操作cookie,Django操作Session,CBV添加装饰器的三种方式,Django中间件,基于中间件开发程序

Django框架之Cookie和Session概念,Django操作cookie,Django操作Session,CBV添加装饰器的三种方式,Django中间件,基于中间件开发程序

时间:2024-07-02 22:08:34浏览次数:19  
标签:session 中间件 request Django Session Cookie cookie def

Ⅰ Django框架之Cookie和Session概念

【一】Cookie与Session的发展史

  • Cookie和Session是用来在Web应用程序中跟踪用户会话数据的两种常用技术。

【1】Cookie的发展史

  • 1994年,网景通信公司推出了第一个浏览器Cookie技术。
  • Cookie是存储在用户计算机上的小型文本文件,用于跟踪用户在网站上的活动。
  • 初始版本的Cookie只能存储很少的数据,并且没有强制加密机制,容易被恶意用户篡改或窃取。
  • 因此,随着互联网的快速发展,Cookie引起了一系列安全和隐私问题。

【2】Session的发展史:

  • 由于Cookie存在的局限性,Web开发人员开始寻找更安全、可靠的替代方案。
  • 1997年,Sun Microsystems提出了基于服务器的会话管理方案,即Session。
  • Session是在服务器端存储用户会话数据的一种技术。
  • 每当用户访问网站时,服务器会为其创建一个唯一的Session标识符(Session ID),并将会话数据存储在服务器上。
  • Session ID一般通过Cookie或URL参数传递给客户端,用于识别用户的会话状态。

【3】Cookie和Session的关系:

  • 在实际应用中,Cookie和Session通常结合使用。当用户首次访问网站时,服务器会为其分配一个唯一的Session ID,并将其存储在Cookie中,发送给客户端保存。
  • 随后,客户端在每次请求中都会携带该Cookie,服务器通过解析Cookie中的Session ID,读取对应的会话数据,实现用户状态的跟踪和管理。

【4】总结:

  • Cookie和Session是Web应用程序中常用的用户会话跟踪技术。
  • Cookie通过在客户端存储小型文本文件,并将会话标识符传递给服务器,实现会话状态的保持。
  • 而Session则是在服务器端存储会话数据,通过Session ID实现对用户会话的追踪。
  • 它们的发展历程与互联网的发展紧密相关,为开发人员提供了更多的选择,以保障安全性和用户体验的提升。

【二】Cookie与Session介绍

# 【一】数据存储过程
最开始的时候存储在内存中
后来学了文件处理 ---将数据存储在文本文件中 --- json 文件中
将数据持久存储 到 MySQL数据库

# 【二】网络并发 web框架的
# HTTP协议
# 1.基于TCP/IP之上的应用层协议
# 2.基于请求与响应的模型
# 3.短连接
# 4.无状态

# 你的服务端是没办法持久化保存你的客户端的状态的

# 【三】网站的发展
# 1.最开始网站 只能渲染图片和资源
# 必须在你的宣传页上面加上你的练习方式 ---> 可以联系
# 5.每个人都可以看得到并且每个人都可以修改
# 让你的浏览器识别是你而不是其他人
# 给你加权限
# 3.解决方案
# 方案一 : 我想让我的服务端保存我的信息 ---> 卸载文本文件中
# 让我的客户端带着我的信息 去服务端查数据 ---> 验证通过就是我自己

# 方案二:
# 我登陆服务端 ---> 服务端给我一个通行证
# 我再将这个通行证存储到本地的浏览器

【1】早期的网站

  • 早期的网站都没有保存用户功能的需求,所有用户访问返回的结果都是一样的
    • 例如新闻、博客、文章...
  • 出现了一些需要保存用户信息的网站
    • 例如淘宝、支付宝、京东...

【2】示例

(1)早期的网站无法保存用户信息

  • 如果不保存用户登录状态,也就意味着用户每次访问网站都需要重复的输入用户名和密码
  • 这对用户来说,体验感极差

(2)解决保存用户信息问题(保存在本地)

  • 当用户第一次登陆成功之后,将用户的用户名和密码返回给用户浏览器,让用户浏览器 保存在本地
  • 之后访问网站的时候浏览器自动将保存在本地的用户名和密码发送给服务端,服务端获取之后自动验证
  • 但是具有极大的安全隐患

(3)优化用户隐私信息(保存在浏览器)

  • 当用户登陆成功之后,服务端产生一个随机字符串(在服务端保存数据,用K:V键值对的形式),交由客户端浏览器保存
  • 之后访问服务端的时候,都带着随机字符串,服务端去数据库中比对是否有匹配到的随机字符串,从而获得用户信息
  • 但是如果截获到当前随机字符串,那么就可以冒充当前用户,其实还是有极大的安全隐患

在web领域没有绝对的安全和绝对的不安全

【3】Cookie

  • 服务器保存在客户端浏览器上的信息都可以称之为cookie
  • 指代服务端让客户端保存的数据(存储在客户端上与用户信息相关的数据)
  • 它的表现形式一般都是k:v键值对(可以有多个)
什么是Cookie
# Cookie就是存储在计算上的小型文本文件,用于记录用户的登陆状态和痕迹
# Cookie只能存储少量的数据,并且不会强制进行机密 ---> 可能会导致用户信息泄露

# 我有一台电脑 ---> 登陆京东 / 登陆百度
# 某一天我的电脑丢了 ---> 不发分子就可以打开我的浏览器  找到 cookie 文件的位置
# 就可以利用我的cookie进行操作

【4】Session

  • 保存在服务器上的信息都可以称之为session
  • 指代服务端保存的跟用户信息相关的数据
  • 它的表现形式一般都是k:v键值对(可以有多个)
服务端
  随机字符串1   用户数据1
  随机字符串2	 用户数据2
  随机字符串3	 用户数据3
客户端
  随机字符串1、随机字符串2、随机字符串3
# 什么是session
# 由于上面说的cookie的巨局限性 : 存储少量数据 不会强制进行机密 cookie 文件被切取
# 于是就出现了 session
# 存储在服务端上面的你个人信息的唯一标识

# 客户端从浏览器输入用户名和密码 ---> 带着给服务端 ---> 服务端负责对输入的用户名和密码进行加密
# 加密完成后 打开我的数据库 将 加密后的字符串添加到我的数据哭当中 ---> 有一个字符串来表示当前加密后的数据---> uuid串
# 将加密后的串的 uuid 串 返回给你的客户端 客户端负责存起来
# 下一次登陆 ---> 带着你的用户名和密码 还要带着我的 sessionid
# 去登录 用户名和密码加密 去数据库差  sessionid 加密串 两者一致登陆成功

【5】token

  • session虽然数据是保存在服务端的,但是挡不住数据量大
  • 解决办法:服务端不再保存数据
    • 登陆成功之后,将一段信息加密处理(用自己独特的加密方式进行加密)
  • 将加密之后的结果拼接在信息后面,整体返回给浏览器保存
  • 浏览器下次访问的时候带着该信息,服务端自动切取前面的一段信息再次使用自己的加密算法进行加密
  • 然后用这段密文与携带过来的密文进行比对
# token
# 不安全 : 一个人没问题 100 10亿 1000亿 10000亿 100000亿
# 数据库存储量较大 查询某一个人的数据的时候的检索时间就会变长
# 也有很大的局限性
# 于是又有了一门新计数  token
# 后面 token 加密手段对 你的传入的数据进行急卖
# 用户名和密码 加上我的时间戳 当时的时间戳 ---> 数据
# 存在浏览器本地但是安全性极高

# md5加密 hash 总归是有重复的时候 常见的 加密串
# 对称加密和非对称加密

【4】总结

  • cookie和 session 都是在浏览器首次访问网站的时候分配的标识
  • cookie就是保存在客户端浏览器上的信息
  • session就是保存在服务端上的信息
  • session是基于cookie工作的(其实大部分的保存用户状态的操作都需要使用cookie)

Ⅱ Django操作cookie

【一】前言引入

【1】引入

  • 虽然cookie是服务端告诉客户端浏览器需要保存内容
  • 但是客户端浏览器可以选择拒绝保存
  • 如果禁止自动保存cookie
  • 那么只要是需要登录的网站都没办法正常登录了

【2】视图函数的返回值(三板斧)

  • 正常返回三板斧对象
return HttpResponse()
return render()
return redirect()
  • 变形
obj = HttpResponse()
return obj

obj1 = render()
return obj1

obj2 = redirect()
return obj2

如果想要操作cookie,必须进行以上变形才可以

【3】设置cookie

obj = HttpResponse()
obj.set_cookie(key,value)
return obj

【4】获取cookie

request.COOKIES.get(key)

【5】设置超时时间

obj = HttpResponse()
obj.set_cookie(key,value,max_age=5)
# 设置超时时间 5s 到期
return obj
  • max_age
    • 设置超时时间,以秒为单位
  • expiress
    • 设置超时时间 针对IE浏览器使用,以秒为单位

【6】注销cookie

obj = HttpResponse()
# 设置超时时间 5s 到期
obj.delete_cookie(key)
return obj

【二】登录功能

简单实现

  • 路由
from django.urls import path,re_path
from  user.views import index,login,home

urlpatterns = [

    path('', index, name="index"),
    path('login/', login, name="login"),
    path('home/', home, name="home"),
  • 视图
from django.shortcuts import render, redirect, reverse

# 实现登陆功能
# 当用户登陆过后才能看到浏览器页面
# 先登录

# Cookie 来实现登陆状态的保存
def index(request):
    return render(request, 'index.html', locals())


def login(request):
    if request.method == "POST":
        username = request.POST.get("username")
        password = request.POST.get("password")
        if username != "silence" and password != "741":
            return redirect(reverse("index"))
        # 如果登陆成功  ---> 存储登陆状态 Cookie
        # 【1】创建一个三板斧对象
        obj = redirect(reverse("index"))
        # 【2】设置Cookie信息
        # obj.set_cookie("sign", "666")
        # 设置过期时间为 3 s 钟
        obj.set_cookie("sign", "666", max_age=3)
        # key : 设置 Cookie的 键
        # value : 设置 Cookie 的值
        # max_age : 过期时间 , 以秒为单位
        # expires :过期时间 但是是针对 IE浏览器 以秒为单位
        # domain : 域名
        # path : 路径
        # secure : 安全组策略
        # httponly : 只限制于 HTTP 请求

        return obj

    obj = render(request, "login.html", locals())
    return obj


def home(request):
    # 【1】先获取到 登陆设置进去的 Cookie 信息
    cookie = request.COOKIES.get("sign")
    # 【2】对Cookie信息进行核对
    if cookie == "666":
        return render(request, "home.html", locals())
    else:
        return redirect(reverse("index"))


def logout(request):
    # 退出登陆 -- 清除掉你电脑上刚才签发的Cookie
    obj = redirect(reverse("index"))
    # 删除Cookie
    obj.delete_cookie("sign")
    return obj
  • 前端
  • index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<p><a href="{% url 'login' %}">点我 进行 登陆</a></p>
<p><a href="{% url 'home' %}">点我访问 home 页面</a></p>
<p><a href="{% url 'logout' %}">点我 退出 登陆</a></p>
</body>
</html>
  • login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>
<form action="" method="post">
    <p>
        username <input type="text" name="username">
    </p>
    <p>
        password <input type="text" name="password">
    </p>
    <p>
        <input type="submit">
    </p>
</form>
</body>
</html>
  • home.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>

<h1>登陆后才能看到我!</h1>
</body>
</html>
  • 先准备登录

  • 登录后获取cookie

  • 有了cookie数据之后点击访问home页面 只有cookie数据照应才能进入

  • 防止页面只是待机 而不是关闭清除数据 防止他人操作

【三】小结

# Django操作Cookie小结
# 【1】设置Cookie
# obj = 三板斧对象
# obj.set_cookie(key,value,max_age=None,expires=None,path=None,domain=None,secure=None,httponly=None)
# key value max_age
# 【2】获取Cookie
# cookie_str = request.COOKIE.get(key)
# 【3】注销Cookie
# obj = 三板斧对象
# obj.delete_cookie(key)

Ⅲ Django操作Session

# 使用session 的前提是迁移数据库!!!
# 使用session 的前提是迁移数据库!!!
# 使用session 的前提是迁移数据库!!!
  • session数据是保存在服务端的,给客户端返回的是一个随机字符串
  • sessionid:随机字符串

【一】设置Session

【1】语法

request.session['key'] = value

【2】设置session内部发生的事情

  • 产生一个随机字符串
  • 表中存储随机字符串与加密数据的对应关系
  • 并将产生的随机字符串也给客户端发送一份并让其保存sessionid:随机字符串

【二】获取Session

【1】语法

request.session.get('key')

【2】获取session内部发送的事情

  • 自动获取客户端请求中的随机字符串
  • 自动去存储session数据的表中比对
  • 如果比对成功自动获取并'解密处理'

【三】设置/获取session多个值

  • 给session设置多个值的时候,存在数据库中的数据仍是一条
  • 但是在取session的时候,可以通过request.session对象获取到设置的多组键值对

【四】django_sessoin表中的session数据

  • django_sessoin表中的数据条数取决于浏览器
    • 同一个计算机(IP地址)上同一个浏览器只会有一条数据生效
    • 同一个计算机(IP地址)上多个浏览器会有多个数据生效
    • 当session过期的时候,可能会出现多条数据对应一个浏览器
      • 但是这些数据不会持久化存储,会被定时清理掉,可以手动清除也可以代码清除
  • 目的是为了节省服务器数据库资源

【五】设置过期时间

# 设置session
request.session['key'] = value
# 设置过期时间
request.session.set_expiry()

# * 如果value是个整数,session会在些秒数后失效。
# * 如果value是个datatime或timedelta,session就会在这个时间后失效。
# * 如果value是0,用户关闭浏览器session就会失效。
# * 如果value是None,session会依赖全局session失效策略。
  • 参数
    • 整数
      • 多少秒过期
    • 日期对象
      • 到指定日期失效
    • 0
      • 一旦退出当前浏览器窗口就失效
    • 不写
      • 失效时间取决于Django内部全局session失效的时间

Django默认的session失效时间是14天

【六】清空session

【1】request.session.delete()

只删除服务端的

  • 该方法用于删除当前用户的Session数据,但会保留Session的Key。
  • 这意味着Session对象本身仍然存在,但其中的数据将被清空。
  • 下次访问时,如果Session没有被重新填充,则会得到一个空的Session对象。

以下是使用request.session.delete()的示例:

def clear_session(request):
    request.session.delete()
    # 其他操作或返回响应

【2】request.session.flush()

服务端和客户端都删除

  • 该方法用于完全删除当前用户的Session,包括Session对象和所有相关数据。
  • 下次访问时,将创建一个新的空Session对象。

以下是使用request.session.flush()的示例:

def clear_session(request):
    request.session.flush()
    # 其他操作或返回响应

【七】保存

1. 数据库Session
SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默认)

2. 缓存Session
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
SESSION_CACHE_ALIAS = 'default'                            # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置

3. 文件Session
SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
SESSION_FILE_PATH = None                                    # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() 

4. 缓存+数据库
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎

5. 加密Cookie Session
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎

其他公用设置项:
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,默认修改之后才保存(默认)

【八】原理剖析

  • request.session['sign'] = "369"内部发生了哪些事
    • Django内部会自动帮我们生成一个随机字符串
    • Django内部自动将随机字符串和对应的数据存储到 django_sessoin 表中
      • 先在内存中产生操作数据的内存
      • 在响应经过Django中间件的时候才去操作数据数据库
  • 将产生的随机字符串返回给客户端浏览器保存
'django.contrib.sessions.middleware.SessionMiddleware',
  • request.session.get("sign")内部发生了哪些事
    • 自动从浏览器请求中获取 sessionid 对应的随机字符串
    • 根据该随机字符串去django_session表中查找对应的数据
      • 如果匹配成功,则将对应的数据取出并以字典的形式封装到request.session中
      • 如果匹配不成功,则request.session中的数据为None

【九】案例演示

# 使用session 的前提是迁移数据库!!!
  • 先进行迁移数据库

  • 进行登录会多出sessionid串

  • 数据库会多出一条数据

  • 如果sessionid不对 在进行登录 会登录不了 并且会清理掉页面数据

代码演示

  • 路由
from django.urls import path,re_path
from  user.views import index,login,home

urlpatterns = [

    path('', index, name="index"),
    path('login/', login, name="login"),
    path('home/', home, name="home"),
  • 视图
from django.shortcuts import render, redirect, reverse

# 实现登陆功能
# 当用户登陆过后才能看到浏览器页面
# 先登录

# Cookie 来实现登陆状态的保存
def index(request):
    return render(request, 'index.html', locals())


def login(request):
    if request.method == "POST":
        username = request.POST.get("username")
        password = request.POST.get("password")
        if username != "silence" and password != "741":
            return redirect(reverse("index"))
        # 如果登陆成功  ---> 存储登陆状态 Cookie
        # 【1】创建一个三板斧对象
        obj = redirect(reverse("index"))
        # 【2】设置Cookie信息
        # obj.set_cookie("sign", "666")
        # 设置过期时间为 3 s 钟
        obj.set_cookie("sign", "666", max_age=3)
        # key : 设置 Cookie的 键
        # value : 设置 Cookie 的值
        # max_age : 过期时间 , 以秒为单位
        # expires :过期时间 但是是针对 IE浏览器 以秒为单位
        # domain : 域名
        # path : 路径
        # secure : 安全组策略
        # httponly : 只限制于 HTTP 请求

        return obj

    obj = render(request, "login.html", locals())
    return obj


def home(request):
    # 【1】先获取到 登陆设置进去的 Cookie 信息
    cookie = request.COOKIES.get("sign")
    # 【2】对Cookie信息进行核对
    if cookie == "666":
        return render(request, "home.html", locals())
    else:
        return redirect(reverse("index"))


def logout(request):
    # 退出登陆 -- 清除掉你电脑上刚才签发的Cookie
    obj = redirect(reverse("index"))
    # 删除Cookie
    obj.delete_cookie("sign")
    return obj
  • 前端
  • index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<p><a href="{% url 'login' %}">点我 进行 登陆</a></p>
<p><a href="{% url 'home' %}">点我访问 home 页面</a></p>
<p><a href="{% url 'logout' %}">点我 退出 登陆</a></p>
</body>
</html>
  • login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>
<form action="" method="post">
    <p>
        username <input type="text" name="username">
    </p>
    <p>
        password <input type="text" name="password">
    </p>
    <p>
        <input type="submit">
    </p>
</form>
</body>
</html>
  • home.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>

<h1>登陆后才能看到我!</h1>
</body>
</html>

Ⅳ CBV添加装饰器的三种方式

from django.views import View
from django.utils.decorators import method_decorator
import time


def timer(func):
    def inner(*args, **kwargs):
        start_time = time.time()
        res = func(*args, **kwargs)
        end_time = time.time()
        print("执行时间:", end_time - start_time, "s")
        return res

    return inner


# 方案二:放到类上面
# @method_decorator(timer, name="get")
class RegisterView(View):
    # 方案一 : 放到指定的函数上面
    # @method_decorator(timer)
    def get(self, request):
        print(request.path)
        print(request)
        int("a")
        time.sleep(3)
        return render(request, "register.html", locals())

    # 方案三:类视图 ---> as_view() ---> 里面的 view() ---> self.dispatch()
    # 因为每一个触发的类视图函数都会走 dispatch 相当于给所有人添加一个装饰器
    @method_decorator(timer)
    def dispatch(self, request, *args, **kwargs):
        # Try to dispatch to the right method; if a method doesn't exist,
        # defer to the error handler. Also defer to the error handler if the
        # request method isn't on the approved list.
        if request.method.lower() in self.http_method_names:
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)

Ⅴ Django中间件

【一】Django中间件介绍

# 在Djangoode请求生命周期中
# 浏览器发起请求 ---> wsgiref
# Django的 中间件
# Django的urls
# Django views
# Django的 处理模版模型 数据库 ...
# Djangode向应对象
# 会给 Django的路由
# Django的中间件
# wsgiref    
# 客户端解包渲染

【1】什么是Django中间件

# Django的中间件其实就是一个第三方的组件
# 组件可以启动 也可以 弃用

# 在Django的中间件中 对请求和响应进行处理
# 只有符合所有规定的请求和响应才能完成交互

# 中间件是依次执行的
# 返回的时候走中间件也是有顺序的
  • Django中间件是一个轻量级、可重用的组件,用于处理Django请求和响应的过程。
  • 它提供了对请求和响应进行全局处理的机制,可以在请求达到视图之前进行预处理或在响应返回给客户端之前进行后处理。
  • 中间件是按照顺序依次执行的,每个中间件都可以对请求和响应进行修改、补充或处理。
  • 在Django的settings.py配置文件中,通过MIDDLEWARE设置来定义中间件的顺序。

【2】作用:

# 【1】请求和响应处理
# 预处理请求
# 后处理响应
# 【2】认证和授权
#  认证 : 要符合制定的身份才能访问
#  授权 : 对某个具有角色的用户授予权限
# 【3】异常处理
# 对全局的异常进行补货和处理
# 【4】性能优化
# 监控请求的进入 统计访问量
# 性能检测 测一下每一个接口的响应时间
  • 认证和授权:
    • 中间件可以在请求到达视图之前进行用户认证和权限验证,确保只有经过授权的用户才能访问敏感资源。
  • 请求和响应处理:
    • 中间件可以在请求到达视图之前对请求进行预处理
      • 例如添加请求头信息、检查请求参数的合法性等操作。
    • 同时,在视图函数返回响应给客户端之前,中间件还可以对响应进行后处理
      • 例如添加额外的响应头、包装响应数据等操作。
  • 异常处理:
    • 中间件还可以捕获视图函数中可能抛出的异常,并做相应的处理
      • 例如记录异常日志、返回自定义错误信息等。
  • 性能优化:
    • 通过中间件,可以对请求进行性能监测、缓存处理、压缩响应等操作,提升网站的整体性能。

【二】Django中间件源码分析

【1】默认的五个中间件详解

(1)SecurityMiddleware

  • django.middleware.security.SecurityMiddleware:
    • 安全中间件负责处理与网站安全相关的任务
    • 例如设置HTTP头部,防止跨站脚本攻击(XSS),点击劫持等。
    • 它可以通过配置自定义安全策略来确保网站的安全性。
rom django.middleware.security import SecurityMiddleware


class SecurityMiddleware(MiddlewareMixin):
    # process_request : 处理request 请求的
    def process_request(self, request):
        ...
    # process_response : 处理视图函数返回的 response 对象的
    def process_response(self, request, response):
        return response

(2)SessionMiddleware

  • django.contrib.sessions.middleware.SessionMiddleware:
    • 会话中间件负责处理用户会话的创建之间存储和检索用户数据。
    • 它基于浏览器提供的Cookie或URL传递的会话ID进行会话跟踪,并将会话数据存储在后端数据库或缓存中,以实现用户状态的跨请求保持。
from django.contrib.sessions.middleware import SessionMiddleware

class SessionMiddleware(MiddlewareMixin):
    # process_request : 处理request 请求的
    def process_request(self, request):
        ...
    # process_response : 处理视图函数返回的 response 对象的
    def process_response(self, request, response):
        return response

(3)CommonMiddleware

  • django.middleware.common.CommonMiddleware:
    • 通用中间件提供了一些常见而关键的HTTP请求处理功能
    • 例如,根据请求的HTTP头信息设置语言、时区等。
    • 此外,它还处理静态文件的serving,包括收集静态文件,为其生成URL,并在开发模式下提供静态文件的serving。
from django.middleware.common import CommonMiddleware

(4)CsrfViewMiddleware

  • django.middleware.csrf.CsrfViewMiddleware:
    • CSRF(Cross-Site Request Forgery)中间件用于防止跨站请求伪造攻击。
    • 它在每个POST请求中验证一个CSRF标记,确保请求是通过合法的表单提交得到的,从而保护用户免受恶意站点的攻击。
from django.middleware.csrf import CsrfViewMiddleware

class CsrfViewMiddleware(MiddlewareMixin):
    # process_request : 处理request 请求的
    def process_request(self, request):
        ...
    def process_view(self, request, callback, callback_args, callback_kwargs):
        ...
    # process_response : 处理视图函数返回的 response 对象的
    def process_response(self, request, response):
        return response

(5)AuthenticationMiddleware

  • django.contrib.auth.middleware.AuthenticationMiddleware:
    • 认证中间件负责处理用户身份认证相关的任务
    • 例如将认证信息关联到请求对象上,为每个请求提供一个user对象,以便在请求处理过程中轻松地获取和使用用户身份信息。

(6)MessageMiddleware

  • django.contrib.messages.middleware.MessageMiddleware:
    • 消息中间件用于在请求处理过程中存储和传递临时的、一次性的用户消息。
    • 它允许在HTTP重定向之间跨请求传递消息,例如成功或错误提示,以改善用户体验。

(7)XFrameOptionsMiddleware

  • django.middleware.clickjacking.XFrameOptionsMiddleware:
    • 点击劫持中间件用于防止页面被嵌入到其他网站中,从而提供一定的点击劫持保护。
    • 它通过设置X-Frame-Options HTTP头部来限制页面的显示方式,从而防止恶意网页通过iframe等方式嵌入当前网页。

【三】总结

# 观察发现每一个中间件都有固定的两个请求
# process_request 处理请求进来的
# process_response 处理响应出去的

# 可选的方法
# process_view 执行视图之前会触发

 

# 【一】请求进入的时候会走每一个中间件的 process_request
# process_request 走的顺序是从上至下依次走
 MyMiddleWare request request request 进来了 
 MyMiddleWareOne request request request 进来了 
 
# 【二】走每一个中间件的 process_view 
# process_view 走的顺序是从上至下依次走
 MyMiddleWare process_view 进来了 
 MyMiddleWareOne process_view 进来了 
 
# 【三】进入到指定的视图函数中
/register/
<WSGIRequest: GET '/register/'>
[02/Jul/2024 04:07:59] "GET /register/ HTTP/1.1" 200 156
执行时间: 3.0085182189941406 s

# 【四】响应回去的时候走 process_response
# process_response 走的顺序是 从下至上 依次走
 MyMiddleWareOne response response response  进来了
 MyMiddleWare response response response  进来了

【四】代码实现

放在app文件下的py文件

  • middlewares.py
from django.utils.deprecation import MiddlewareMixin


class MyMiddleWare(MiddlewareMixin):
    def process_request(self, request):
        # if request.headers.get("Host").split(":")[0] == "localhost":
        #     raise Exception("非法请求")

        print(" MyMiddleWare request request request 进来了 ")

    def process_exception(self, request, exception):
        if exception:
            pass

    def process_view(self, request, callback, callback_args, callback_kwargs):
        print(" MyMiddleWare process_view 进来了 ")

    def process_response(self, request, response):
        print(" MyMiddleWare response response response  进来了")
        return response


class MyMiddleWareOne(MiddlewareMixin):
    def process_request(self, request):
        print(" MyMiddleWareOne request request request 进来了 ")

    def process_view(self, request, callback, callback_args, callback_kwargs):
        print(" MyMiddleWareOne process_view 进来了 ")

    def process_response(self, request, response):
        print(" MyMiddleWareOne response response response  进来了")
        return response

在settings里面引入 格式:文件夹名.py文件名.类名

  • user.middlewares.MyMiddleWare
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'user.middlewares.MyMiddleWare',
]
  • 运行 终端 展示
MyMiddleWare request request request 进来了 
 MyMiddleWareOne request request request 进来了 
 MyMiddleWare process_view 进来了 
 MyMiddleWareOne process_view 进来了 
888
888
888  # 这三个888是cookie代码中的数据
 MyMiddleWareOne response response response  进来了
 MyMiddleWare response response response  进来了

Ⅵ 基于中间件开发程序

【1】初版

# 开发程序 : 给三个平台同事发送同一条消息
# 微信 / 钉钉  / QQ

# 方案一:开发每一个平台的个性化发送功能 总结起来统一发送
# 放在一个py文件下 直接运行
def wechat(content):
    print("微信发送消息:", content)


def dingtalk(content):
    print("钉钉发送消息:", content)


def qq(content):
    print("QQ发送消息:", content)

def send_all(content):
    wechat(content)
    dingtalk(content)
    qq(content)


send_all("hello, 大家好!")

# 方案二:上面的代码太多了 ---> 分层开发
# 创建三个文件 每一个文件里面封装自己的参数及请求

【2】分模块开发

send_one
  dingdingtalk.py
  main.py
  qq.py
  wechat.py
# dingdingtalk .py
class DD():
    def __init__(self):
        # 初始化链接qq 的参数配置项
        # 创建链接 ...
        ...

    def send(self, content):
        print("DD发送消息:", content)


#  QQ .py
class QQ():
    def __init__(self):
        # 初始化链接qq 的参数配置项
        # 创建链接 ...
        ...

    def send(self, content):
        print("QQ发送消息:", content)


#  wechat .py
class Wx():
    def __init__(self):
        # 初始化链接qq 的参数配置项
        # 创建链接 ...
        ...

    def send(self, content):
        print("Wx发送消息:", content)


# main .py
from dingdingtalk import DD
from qq import QQ
from wechat import Wx


def send_content(content):
    cls_list = [DD, QQ, Wx]
    for i in cls_list:
        send = getattr(i(), 'send')
        send(content)


send_content(content="hellow ")

【3】终版

send_two
  dingdingtalk.py
  main.py
  mobile.py
  qq.py
  settings.py
  wechat.py
#  dingdingtalk .py
class DD():
    def __init__(self):
        # 初始化链接qq 的参数配置项
        # 创建链接 ...
        ...

    def send(self, content):
        print("DD发送消息:", content)

# QQ .py
class QQ():
    def __init__(self):
        # 初始化链接qq 的参数配置项
        # 创建链接 ...
        ...

    def send(self, content):
        print("QQ发送消息:", content)

# wechat .py
class Wx():
    def __init__(self):
        # 初始化链接qq 的参数配置项
        # 创建链接 ...
        ...

    def send(self, content):
        print("Wx发送消息:", content)


#  main .py
from dingdingtalk import DD
from qq import QQ
from wechat import Wx


def send_content(content):
    cls_list = [DD, QQ, Wx]
    for i in cls_list:
        send = getattr(i(), 'send')
        send(content)


#settings .py
MODEL_LIST = [
    # 文件夹名字.文件夹名字.文件夹名字.py文件名.类名
    "scripts.send_meeage.send_two.dingdingtalk.DD",
    "scripts.send_meeage.send_two.qq.QQ",
    "scripts.send_meeage.send_two.wechat.Wx",
    "scripts.send_meeage.send_two.mobile.Phone",
]



#  main .py
import settings
import importlib

import os
import sys

file_path = os.path.dirname(__file__)
sys.path.insert(0, file_path)


def main(content):
    for path in settings.MODEL_LIST:
        model_path, model_name = path.rsplit(".", maxsplit=1)
        model_obj = importlib.import_module(model_path)
        cls = getattr(model_obj, model_name)
        obj = cls()
        obj.send(content)


if __name__ == '__main__':
    main(content="hello ")

标签:session,中间件,request,Django,Session,Cookie,cookie,def
From: https://www.cnblogs.com/zyb123/p/18280638

相关文章

  • Django 多对多关系
    多对多关系作用Django中,多对多关系模型的作用主要是为了表示两个模型之间的多对多关系。具体来说,多对多关系允许一个模型的实例与另一个模型的多个实例相关联,反之亦然。这在很多实际应用场景中非常有用,比如:博客和标签:一篇博客文章可以有多个标签,一个标签也可以属于多篇博客......
  • flasksession伪造和jwt伪造
    flasksession伪造基本理论session是在服务端用来存储用户信息的,类似于来宾登记表,通过http报文中的cookie进行传递.由于flask轻量级的设计,因此session是存储在客户端的,因此也带来了flasksession伪造的风险.flask中的session通过app.secret_key=...来设置.flasksession通......
  • Django3在网页上生成二维码
    1.安装包pipinstalldjango-qr-code2.在django项目的settings.py中,安装app打开项目的settings.py,找到INSTALLED_APPS,在这里增加一条'qr_code'INSTALLED_APPS=[...,'rest_framework','qr_code',...]3.在渲染的html文件中,导入模板{%loadqr_co......
  • CS253 Laboratory session
    CS253 Laboratorysession4Part 1: Disassembling code, going backwards, converting an executable back to Assembly Language.Preamble: Remember that whatever language you are using ultimately it runs as Machine Code onthe processor......
  • 57.Django框架之序列化输出
    Django框架【一】序列化组件1)使用案例在前端获取到后端用户表里面的所有数据,并且格式是列表套字典#创建模型表classUser(models.Model): username=models.CharField(max_length=32,verbose_name="姓名")age=models.IntegerField(verbose_name="年龄")2)基于J......
  • cookie,session,token它们到底是怎么一回事?一篇文章,彻底明白!
    前言web1.0强调的是资源的共享:http协议是无状态的web2.0强调资源的交互:为了防止信息被篡改,请求与请求之间就涉及到了身份的验证web3.0强调共赢cookiecookie是一种客户端存储技术cookie的产生背景与HTTP协议的无状态特性密切相关。HTTP协议本身无法识别两个请求是否来自同......
  • 自动化(爬虫)工具 DrissionPage SessionPage模式 API介绍 使用笔记(三)
    自动化(爬虫)工具DrissionPageSessionPage模式API介绍使用笔记(三)目录启动驱动启动配置常用方法(API)启动最简单的启动方式,更多启动方式见这里fromDrissionPageimportSessionPage#session_or_options:Session对象或SessionOptions对象#timeout:超时时间(秒)o......
  • net core 中如何使用session
    原文链接:https://zhuanlan.zhihu.com/p/6373955031,在ConfigureServices方法里加入services.AddSession()配置publicvoidConfigureServices(IServiceCollectionservices){services.AddSession();} 2,在Configure里介入app.UseSession()配置注意app.UseSession();这句要......
  • 华为云技术专家硬核分享,云原生中间件如何加速业务发展
    本文分享自华为云社区《云原生中间件,构筑软件安全可信的连接桥梁》,作者:华为云PaaS服务小智。近日,在华为云开发者大会2024期间,来自华为云PaaS服务,中间件领域产品团队的资深专家、技术总监、高级产品经理等大咖们发表了以“云原生中间件,构筑软件安全可信的连接桥梁”为主题的专题......
  • day33-Django3.2(二)
    四、视图django的视图主要有2种,分别是函数视图和类视图.现在刚开始学习django,我们先学习函数视图(FBV),后面再学习类视图[CBV].4.1、请求方式web项目运行在http协议下,默认肯定也支持用户通过不同的http请求发送数据来。django支持让客户端只能通过指定的Http请求来访问到项......