Django Cookie和Session

Django Cookie和Session

【一】介绍

【1】起因

  • HTTP协议四大特性
    1. 基于请求响应模式:客户端发送请求,服务端返回响应
    2. 基于TCP/IP之上:作用于应用层之上的协议
    3. 无状态:HTTP协议本身不保存客户端信息
    4. 短链接:1.0默认使用短链接,请求-响应后断开连接
  • 因为无状态
    • 导致客户端和服务端无法正常长时间的通讯
    • 所以需要一种方法来打破这种情况
  • Cookie和Session是Web开发中常用的两种持久化会话状态的方法

【2】Cookie和Session

(1)介绍

  • cookie

    • Cookie是服务器发送到用户浏览器并保存在浏览器上的一块数据
    • 他会在浏览器下一次向服务器发送请求时被携带并发送到服务器上
  • session

    • Session是另一种保存用户数据的方法,但数据是保存到服务器端
    • Session通过生成一种叫做Session ID唯一标识符,保存在cookie中或者通过URL传递,以便在多个请求中可以识别和跟踪用户

(2)关系

  • session和cookie的主要关系是
    • session通常使用cookie来存储Session ID
    • 以便在多个请求之间跟踪用户
    • 但是也可以通过其他方式(URL)

(3)异同

  • 存储位置:
    • cookie存储在客户端,session存储在服务端
  • 安全性:
    • 由于cookie存在客户端,所以安全性较低
    • 如果信息是密码这种敏感信息,还是用session
  • 生命周期:
    • cookie可以设置过期时间,如果不设置时间,那么关闭浏览器时,cookie就会被删除
    • session的生命周期通常由服务器设置,当用户关闭浏览器并长时间误操作,session也会过期然后删除
  • 存贮容量:
    • cookie的大小通常有限制(4KB)
    • session理论上是没有大小限制的

【二】Django操作cookie

【1】语法

  • 以HttpResponse为例
  • 另外的两把斧也可以

(1)设置cookie

http_res = HttpResponse()
http_res.set_cookie(key, value)

(2)获取cookie

request.COOKIES.get(key)

(3)设置过期时间

  • 不指定这个参数的话
    • 那么cookie将是会话Cookie
    • 即在浏览器关闭后会被删除
  • max_age默认单位是秒
    • 可以使用datetime模块的timedelta快速换算单位
    • max_age = timedelta(days=1).total_seconds()
  • IE浏览器使用expires这个参数
http_res = HttpResponse()
http_res.set_cookie(key, value, max_age)

(4)注销cookie

http_res = HttpResponse()
http_res.delete_cookie(key)
  • 视图层
def get_cookie(request):
    res = request.COOKIES.get("name")
    print(res)
    return HttpResponse(res)

def set_cookie(request):
    http_res = HttpResponse()
    # 浏览器关闭后会被删除
    http_res.set_cookie("name", "bruce")
    # 5秒后这个cookie会被删除
    # http_res.set_cookie("name", "bruce", max_age=5)
    # 注销cookie
    res = http_res.delete_cookie("name")
    print(res)
    return http_res

在这里插入图片描述

【2】示例

(1)装饰器登录功能

  • 要求
    • 功能界面func需要登录才可以使用,
      • 如果没有登录就跳转到登录界面
    • 登录完成以后,自动跳转到主页
    • 主页不需要进行登录验证
  • 前端(登录)
    • 其他界面显示文字即可
    • 直接HttpResponse
<form action="" method="post">
    <p>username: <input type="text" name="username"></p>
    <p>password: <input type="password" name="password"></p>
    <button class="">提交</button>
</form>
  • 视图层
    • login_decorator:登录验证装饰器
    • login:登陆函数
    • home:主界面
    • func1func2功能界面
def login_decorator(func):
    def inner(request, *args, **kwargs):
        if request.COOKIES.get("login_info"):
            res = func(request, *args, **kwargs)
            return res
        return redirect('/login/')
    return inner

def login(request):
    if request.method == "POST":
        username = request.POST.get("username")
        password = request.POST.get("password")
        # 正常需要和数据库数据校验
        # 这里简单一点
        if username == "bruce" and password == "000":
            response = redirect('/home/')
            response.set_cookie("login_info", username + password)
            return response
    return render(request, 'login.html', locals())

def home(request):
    return HttpResponse("主页")

@login_decorator
def func1(request):
    return HttpResponse("func1")

@login_decorator
def func2(request):
    return HttpResponse("func2")

(2)页面跳转登录功能

  • 在原先的基础上
    • 加上那个界面触发的登录
    • 在登录成功以后返回到那个界面
    • 精髓:发送POST请求带上GET请求的内容
def login_decorator(func):
    def inner(request, *args, **kwargs):
        next_url = request.get_full_path()
        if request.COOKIES.get("login_info"):
            res = func(request, *args, **kwargs)
            return res
        return redirect(f'/login/?next={next_url}')
    return inner


def login(request):
    # http://127.0.0.1:8000/login/?next=/func1/
    # 此时发送的是POST请求
    # 但是携带了get的内容
    if request.method == "POST":
        username = request.POST.get("username")
        password = request.POST.get("password")
        # 正常需要和数据库数据校验
        # 这里简单一点
        if username == "bruce" and password == "000":
            next_url = request.GET.get("next")
            next_url = next_url if next_url else '/home/'
            response = redirect(next_url)
            response.set_cookie("login_info", username + password)
            return response
    return render(request, 'login.html', locals())

【三】Django操作session

【0】准备

  • session是保存在服务器的
  • 那么Django就需要一个文件来保存session数据
  • 这个文件就是在数据迁移时自动创建的表单django_sessoin
  • 即如果新项目想要使用session需要先迁移一下数据

【1】语法

(1)设置session

  • 内部执行过程
    1. 产生一个随机字符串
    2. 保存随机字符串和加密数据
    3. 最后将随机字符串返回给浏览器,存储在cookie中
      • 格式:sessionid:随机字符串
  • 添加多个键值对数据
    • 最终还是对应一个sessionid
request.session['key'] = value

(2)获取session

  • 内部执行过程
    • 获取客户端发来的随机字符串
    • 去存储session的django_sessoin表单中对比查询随机字符串
    • 比对成功自动解密处理数据(根据key找value)
    • 比对失败则request.session中的数据为None
request.session.get('key')

(3)设置过期时间

  • value是整数:多少秒过期
  • value是日期对象:datetime.datetime 对象,会话将在这个指定的日期和时间过期。
  • value是0:退出浏览器窗口就过期
  • 不设置(None),过期策略将依赖于全局session配置
    • 这是django的settings的文件中的session_cookie_age配置
    • 默认是14天
  • 可以不设置,设置了就必须要给值
  • 过期会删除客户端和服务端的session,但是
    • 客户端的自动删除了
    • 服务端的出于性能考虑,并不会立即删除过期的session数据。
    • 可以手动clearsessions 命令来手动清理过期的session。
request.session.set_expiry(value)

(4)清空session

  • delete()
    • 清除当前用户所在服务端的session数据
    • 但是会保留session的键key
    • 如果下次用户来访问时session没有被填充
    • 那么返回的就是一个空的session对象
request.session.delete()
  • flush()
    • 完全删除当前用户的所有session对象和相关数据
    • 包括服务端和客户端
request.session.flush()

(5)多值和多session

  • 同一个用户创建多个数据

    • 报错的只有一个sessionid
  • 同一个计算机,同一个浏览器对应相同的sessionid

  • 同一个计算机,不同浏览器对应不同的sessionid

  • 当session过期时,可能出现多个sessionid对应同一个浏览器

    • 但是过期的数据不会持久化存储,会被定时清理掉
    • 目的是为了节省服务器资源
    • 手动清理clearsessions 命令
  • 视图层

def get_session(request):
    res1 = request.session.get('sign')
    print(f"session第一个数据:{res1}")
    res2 = request.session.get("flag")
    print(f"session第一个数据:{res2}")
    return HttpResponse("获取session成功")


def set_session(request):
    # session添加多个键值对,还是保存在一个sessionid中
    request.session['sign'] = "hello"
    request.session['flag'] = True
    # 十秒后自动清除客户端和服务端的session
    # request.session.set_expiry(10)
    # 关闭浏览器就清除
    # request.session.set_expiry(0)
    return HttpResponse("添加session成功")

在这里插入图片描述

【2】Django配置

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,默认修改之后才保存(默认)

【3】示例

(1)页面跳转登录

  • 和cookie的基本一样就是cookie改成session
def login_decorator(func):
    def inner(request, *args, **kwargs):
        next_url = request.get_full_path()
        if request.session.get("login_info"):
            res = func(request, *args, **kwargs)
            return res
        return redirect(f'/login/?next={next_url}')
    return inner


def login(request):
    # http://127.0.0.1:8000/login/?next=/func1/
    # 此时发送的是POST请求
    # 但是携带了get的内容
    if request.method == "POST":
        username = request.POST.get("username")
        password = request.POST.get("password")
        # 正常需要和数据库数据校验
        # 这里简单一点
        if username == "bruce" and password == "000":
            next_url = request.GET.get("next")
            next_url = next_url if next_url else '/home/'
            response = redirect(next_url)
            # response.sess("login_info", username + password)
            request.session['login_info'] = f"{username}-{password}"
            return response
    return render(request, 'login.html', locals())

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

重塑未来:Web3如何改变我们的数字生活

引言 随着科技的飞速发展&#xff0c;Web3已经成为数字时代的新潮流&#xff0c;其革命性的变革正在渐渐改变着我们的数字生活。本文将深入探讨Web3如何改变我们的数字生活&#xff0c;涉及其意义、应用场景、对未来的影响&#xff0c;以及我们如何适应这一变革&#xff0c;为…

Vue 二次封装组件的艺术与实践

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

[flask]执行上下文的四个全局变量

flask上下文全局变量&#xff0c;程序上下文、请求上下文、上下文钩子 -- - 夏晓旭 - 博客园 (cnblogs.com) 执行上下文 执行上下文&#xff1a;即语境&#xff0c;语意&#xff0c;在程序中可以理解为在代码执行到某一行时&#xff0c;根据之前代码所做的操作以及下文即将要…

macos下 jupyter服务安装和vscode链接密码设置 .ipynb文件

最近收到了一些后缀为.ipynb的文件&#xff0c; 这个文件就是使用jupyter编辑的&#xff0c;于是就需要安装一个jupyter服务&#xff0c; 对于最新版本的jupyter 网上很多的资料都已经过期了&#xff0c;这里以最新版本的jupyter为例。 jupyter lab安装 jupyter 这个工具包含…

基于遗传算法的智能天线最佳阵列因子计算matlab仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 基于遗传算法的智能天线最佳阵列因子计算。智能天线技术利用自适应阵列处理技术改善无线通信系统的性能&#xff0c;尤其是提高接收信号质量、抑制干扰和增强定位能力。在智能…

集合系列(十六) -集合知识回顾整理

一、摘要 在 Java 中&#xff0c;集合大致可以分为两大体系&#xff0c;一个是 Collection&#xff0c;另一个是 Map&#xff0c;都位于java.util包下。 Collection &#xff1a;主要由 List、Set、Queue 接口组成&#xff0c;List 代表有序、重复的集合&#xff1b;其中 Set…

C语言:文件操作详解

什么是文件 文件是是计算机硬盘存储的数据的集合&#xff0c;它可以是文本文档&#xff0c;也可以是图片&#xff0c;程序等等。将数据存储进文件内可以很好的保存数据&#xff0c;方便程序员对文件的操作。 文件的类型 一般根据存储数据类型的不同可以分为二进制文件和文本文…

python的神奇bug2

今天测试出一个很诡异的bug&#xff0c; 这个错误还真的很难发现 测试1 a [1,10,100] for i in a:print(i)if(i10):a[20,30,-1]一般来说我们在进行迭代时&#xff0c;a这个值时不能改动的&#xff0c;但是现在的问题时如果我不小心给改动了呢&#xff0c;结果如下 也就是说…

通过Jmeter准备压测数据-mysql示例

1、新建线程组 总共30万条数据 2、创建jdbc链接 创建jdbc连接配置 配置mysql连接 需要在jmeter安装的路径\apache-jmeter-5.6.3\lib\ext 目录下添加mysql 驱动 3、创建jdbc请求 jdbc链接名称需要与上一步中的保持一致&#xff0c;同时添加insert语句 例如 INSERT INTO test…

让手机平板成为AI开发利器:AidLux

想ssh登录自己的手机吗&#xff1f; 想在手机上自由的安装lynx、python、vscode、jupyter甚至飞桨PaddlePaddle、Tensorflow、Pytorch和昇思Mindspore吗&#xff1f; 那么看这里....装上AidLux&#xff0c;以上全都有&#xff01; AidLux是一个综合的AI开发平台&#xff0c;…

nvm安装以后,node -v npm 等命令提示不是内部或外部命令

因为有vue2和vue3项目多种&#xff0c;所以为了适应各类版本node,使用nvm管理多种node版本&#xff0c;但是当我按教程安装nvm以后&#xff0c;nvm安装以后&#xff0c;node -v npm 等命令提示不是内部或外部命令 首先nvm官网网址&#xff1a;https://github.com/coreybutler/…

java调用jacob进行文件转换ppt转pdf或者png

java调用jacob进行文件转换ppt转pdf或者png 前情提要 最近项目上&#xff0c;遇到一个复杂的ppt&#xff0c;最终要求是要将ppt每一页转成图片原本这个是不难&#xff0c;网上一搜一大堆案例&#xff0c;外加我本身也比较精通aspose&#xff0c;那还不是分分钟搞定。结果就是…

实测梳理一下kafka分区分组的作用

清空topickafka-topics.sh --bootstrap-server localhost:9092 --delete --topic second创建分区kafka-topics.sh --create --bootstrap-server localhost:9092 --replication-factor 1 --partitions 3 --topic second发kafka-console-producer.sh --bootstrap-server localhos…

Node.js【入门级】

node 可以脱离浏览器来执行js代码,没有DOM和BOM对象,针对后端可以编写接口&#xff0c;提供网页资源&#xff0c;前端可以集成各种工具&#xff08;承上启下&#xff09;Buffer Buffer相关操作 let buf Buffer.alloc(10) console.log(buf); let buf_2 Buffer.allocUnsafe(10…

【GitLab】Ubuntu 22.04 快速安装 GitLab

在 Ubuntu 22.04 上安装最新版本的 GitLab&#xff0c;可以按照以下步骤操作&#xff1a; 1. 更新系统&#xff1a; 在终端中执行以下命令以确保系统是最新的&#xff1a; sudo apt update sudo apt upgrade2. 安装依赖&#xff1a; 安装 GitLab 所需的依赖包&#xff1a; …

Hack.Summit() 2024再添亮点:Morphism CEO Cecilia Hsueh确认出席

随着Web3技术的风起云涌&#xff0c;区块链行业正在全球范围内以前所未有的速度崭露头角。而在这场变革的浪潮中&#xff0c;备受瞩目的区块链盛会——Hack.Summit() 2024区块链开发者大会&#xff0c;将于2024年4月9日至10日&#xff0c;在香港数码港拉开帷幕。这不仅标志着Ha…

图书推荐|Django+Vue.js商城项目实战

一线资深架构师 凝聚近十年大型系统开发经验 倾力打造 双色印刷 适合&#xff1a;项目演练求职应聘技术提升 全新&#xff1a;Django 4.x与Vue.js 3.x全栈技术 易学&#xff1a;娓娓道来图示指引原理剖析步骤解说代码详注 真实企业级项目技术细节完整揭秘&#xff0c;照着做就…

逆向案例9--小鹅通视频m3u8内容解密--含简单webpack

视频网址&#xff1a;https://app4nseessp8638.h5.xiaoeknow.com/v2/course/alive/l_65b9e8dfe4b064a83b90e102?type2&app_idapp4nseessp8638&channel_id&res_type4&pro_id&res_idl_65b9e8dfe4b064a83b90e102 按照惯例&#xff0c;刷新网站&#xff0c;搜…

Docker数据卷挂载

一、容器与数据耦合的问题: 数据卷是虚拟的&#xff0c;不真实存在的&#xff0c;它指向文件中的文件夹 &#xff0c;属主机文件系统通过数据卷和容器数据进行联系&#xff0c;你改变我也改变。 解决办法&#xff1a; 对宿主机文件系统内的文件进行修改&#xff0c;会立刻反应…

MyBatis入门01

MyBatis入门01 文章目录 MyBatis入门01前言一、搭建环境1.新建一个普通的maven项目2.删除src目录3.导入maven依赖&#xff1a;mysql驱动&#xff08;操作jdbc&#xff09;&#xff0c;juint&#xff0c;mybatis注意&#xff1a;要假如builder标签&#xff0c;预防配置文件不可导…