Django会话技术

news2024/12/23 18:11:16

文章目录

  • Cookie
    • 实践
      • 运行结果
  • CSRF
    • 防止CSRF
  • Session
    • 实践


Cookie

	理论上,一个用户的所有请求燥作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话,二者不能混淆,而web应用程序是使用HTTP协议传输数据的。HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。要跟踪该会话,必须引入一种机制。
	Cookie就是这样的一种机制。它可以弥补HTTP协议无状态的不足。在Session出现之前,基本上所有的网站都采用Cookie来跟踪会话。
	Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。
	由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。

	cookie本身由服务器生成,通过Response将cookie写到浏览器上,下一次访问,浏览器会根据不同的规则携带cookie过来。
	注意:cookie不能跨浏览器,一般不跨域
	
	设置cookie(使用response设置)
		response.set_cookie(key,value[,max_age=None,expires=None])
			max_age:整数 单位为秒,指定cookie过期时间
					设置为None:浏览器关闭失效,默认值
			expires:指定过期时间,还支持datetime或timedelta,可以指定一个具体日期时间
				expires=datetime.datetime(2030, 1, 1, 2, 3, 4)
				或 datetime.datetime.now() + datetime.timedelta(days=10)

			注意:max_age和expries两个选一个指定
			# response.set_cookie( 'username', username, max_age=10)
			# response.set_cookie( "username", username1, expires=d)

获取cookie(使用request获取):
	request.COOKIES.get('username')
删除cookie(使用response删除):
	response.delete_cookie('username')

cookie存储到客户端
优点:
	数据存在在客户端,减轻服务器端的压力,提高网站的性能。
缺点:
	安全性不高: 在客户端机很容易被查看或破解用户会话信息

在这里插入图片描述

实践

新建一个项目 Day05DjangoPro02,我就不写连接数据库了
在这里插入图片描述
路由Day05DjangoPro02\urls.py

from django.contrib import admin
from django.urls import path
from App.views import *

urlpatterns = [
    path('', index),
    path('index/', index, name='index'),
    path('login/', login, name='login'),
    path('logout/', logout, name='logout'),

    path('admin/', admin.site.urls),

]

App\views.py

import datetime

from django.shortcuts import render, redirect, reverse, HttpResponse


# 注销、登出
def logout(request):
    # 不能直接return render重新渲染是不可以的,我们一定要重新进入index页面,所以要跳转一下,路由也要变
    response = redirect(reverse('index'))
    # 删除cookie:注销
    response.delete_cookie('userid')
    return response


# 首页
def index(request):
    # cookie
    userid = request.COOKIES.get('userid', 0)  # 如果没找到就默认给个0

    # 获取登录的用户(查数据库,这边就不写查数据库了)
    user = None
    if userid != 0:
        user = {'username': 'admin'}

    return render(request, 'index.html', {'user': user})


# 登录
def login(request):
    if request.method == 'GET':
        return render(request, 'login.html')
    elif request.method == 'POST':
        # 1.先接收前端提交过来的数据
        username = request.POST.get('username')
        password = request.POST.get('password')
        # 2. 登录验证
        # 查数据库,这边就不写数据库了
        if username == 'admin' and password == '123456':
            # 3. 设置cookie
            # 注意:a. cookie是存储在浏览器本地
            #      b. cookie不能跨域,不能跨浏览器
            #      c. cookie存储的内容是字符串,不能为中文,一般存储大小不要超过4KB
            #      d. cookie由后端生成创建,返回给前端保存
            response = redirect(reverse('index'))
            # response.set_cookie('userid', 666)  # 创建cookie
            # 默认设置是当前浏览器打开的时候,如果把整个浏览器关掉,再打开userid就会没有
            # 一般需要设置过期时间
            # response.set_cookie('userid', 999, max_age=7 * 24 * 3600)  # 7天 max_age:秒
            # response.set_cookie('userid', 555, expires=datetime.datetime(2023, 8, 31, 3, 4, 5))
            # 过期具体的日期 expires 2023.8.31 3小时4分5秒
            response.set_cookie('userid', 555, expires=datetime.datetime.now() + datetime.timedelta(days=10))  # 10天后的日期
            # 4. 跳转到登录页面
            return response
        return HttpResponse('登录失败,账号是admin,密码是123456')

templates\login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
    <h2>登录</h2>
    <hr>
    <form action="" method="post">
        {% csrf_token %}
        <p>用户名:<input type="text" name="username" /></p>
        <p>密码:<input type="text" name="password" /></p>
        <p><button>登录</button></p>
    </form>
</body>
</html>

templates\index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
    <h2>首页</h2>
    <hr>
    {% if user %}
        当前登录的用户:{{ user.username }}
         <a href="{% url 'logout' %}">注销</a>
    {% else %}
         <a href="{% url 'login' %}">登录</a>

    {% endif %}
</body>
</html>

运行结果

登录前:http://127.0.0.1:8000
在这里插入图片描述

在这里插入图片描述
登录成功,看cookie
在这里插入图片描述

点击注销,看cookie

在这里插入图片描述


CSRF

  • CSRF全拼为Cross Site Request Forgery,跨站请求伪造。
  • CSRF指攻击者盗用了你的身份,以你的名义发送恶意请求
    • 包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账…
  • 造成的问题: 个人隐私泄露以及财产安全。

在这里插入图片描述

防止CSRF

  • Django下的CSRF预防机制
    django第一次响应来自某个客户端的请求时,会在服务器端随机生成一个 token,把这个 token 放在cookie里。然后每次 POST请求都会带上这个 token,这样就能避免被 CSRF攻击。
  • django在setting.py文件中有一个中间件CsrfViewMiddleware,django会在内部自动生成token,并且将token返回给前端。这个cookie主要是跟后台做校验的,在内部会自己做校验。

在这里插入图片描述

  • 方法一,不推荐,在setting.py文件中把中间件注释,
    在这里插入图片描述

  • 方法2:在Post请求时,表单中添加 {% csrf_token %}
    通过自动加token的方式防止CSRF

    <form action="" method="post">
    	{% csrf_token %}
    </form>
    
  • CSRF verification failed. Request aborted.
    CSRF验证失败。请求中止。在这里插入图片描述

Session

服务器端会话技术,依赖于cookie.
	django中启用SESSION
		settings中
			INSTALLED_APPS:
				'django.contrib.sessions'
			MIDDLEWARE:
				'django.contrib.sessions.middleware.SessionMiddleware'
				
	基本操作
		设置Sessions值 (使用request设置)
			request.session['user_id'] = user.id
			request.session.set_expiry(86400) # 设置过期时间
		
		获取Sessions值
			get(key,default=None) 根据键获取会话的值
			username = request.session.get("user_id")
			#或 session_name = request.session["session_name"]
		
		删除Sessions值
			# 获取当前请求的session的key
			session_key = request.session.session_key
			del request.session[session_key]
			# request.session.delete(session_key)
			flush()	删除当前的会话数据并删除会话的cookie
		
		clear()	清除所有会话
		
		数据存储到数据库中会进行编码,使用的是Base64
	每个HttpRequest对象都有一个session属性,也是一个类字典对象

settings中本身就配置好了

在这里插入图片描述

生成迁移文件: python manage.py makemigrations
执行迁移: python manage.py migrate

Session数据存储到数据库中会进行编码,使用的是Base64。如果我们设置了Session数据库是有东西的。
在这里插入图片描述

实践

在之前上面写好的基础改一下,把cookie改成session。
App\views.py

import datetime

from django.shortcuts import render, redirect, reverse, HttpResponse


# 注销、登出
def logout(request):
    # 不能直接return render重新渲染是不可以的,我们一定要重新进入index页面,所以要跳转一下,路由也要变
    response = redirect(reverse('index'))
    # 删除cookie:注销
    # response.delete_cookie('userid')

    # 删除session:注销
    session_key = request.session.session_key  # 得到的是当前session会话的sessionid(前端cookie存的sessionid的值)
    print(session_key)
    request.session.delete(session_key)  # 数据库里的session_key那条记录也会被删掉

    return response


# 首页
def index(request):
    # # cookie
    # userid = request.COOKIES.get('userid', 0)  # 如果没找到就默认给个0

    # session
    userid = request.session.get('userid', 0)  # 一般我们都设置默认值,默认给个0, 如果不设置就是None

    # 获取登录的用户(查数据库,这边就不写查数据库了)
    # user= UserModel.objects.filter(id=userid).first()
    #                          .filter(id=None)  会报错!!!
    user = None
    if userid != 0:
        user = {'username': 'admin'}

    return render(request, 'index.html', {'user': user})


# 登录
def login(request):
    if request.method == 'GET':
        return render(request, 'login.html')
    elif request.method == 'POST':
        # 1.先接收前端提交过来的数据
        username = request.POST.get('username')
        password = request.POST.get('password')
        # 2. 登录验证
        # 查数据库,这边就不写数据库了
        if username == 'admin' and password == '123456':
            response = redirect(reverse('index'))
            # # 3. 设置cookie
            # # 注意:a. cookie是存储在浏览器本地
            # #      b. cookie不能跨域,不能跨浏览器
            # #      c. cookie存储的内容是字符串,不能为中文,一般存储大小不要超过4KB
            # #      d. cookie由后端生成创建,返回给前端保存
            # response = redirect(reverse('index'))
            # # response.set_cookie('userid', 666)  # 创建cookie
            # # 默认设置是当前浏览器打开的时候,如果把整个浏览器关掉,再打开userid就会没有
            # # 一般需要设置过期时间
            # # response.set_cookie('userid', 999, max_age=7 * 24 * 3600)  # 7天 max_age:秒
            # # response.set_cookie('userid', 555, expires=datetime.datetime(2023, 8, 31, 3, 4, 5))
            # # 过期具体的日期 expires 2023.8.31 3小时4分5秒
            # response.set_cookie('userid', 555, expires=datetime.datetime.now() + datetime.timedelta(days=10))  # 10天后的日期

            # 3. 设置session
            request.session['userid'] = 888
            request.session.set_expiry(7 * 24 * 3600)  # 7天 max_age:秒

            # 4. 跳转到登录页面
            return response
        return HttpResponse('登录失败,账号是admin,密码是123456')

http://127.0.0.1:8000/login/

登录之后,我们可以看到生成了一个cookie,名字叫sessionid,所以说session是依赖于cookie,但是在cookie存的是sessionid,并且它的值是经过编码的

在这里插入图片描述
在这里插入图片描述

看sessionid这个值,跟数据库里session_key是对应的。session_data也是经过编码加密的,这个数据里面会存放我们刚刚添加的userid的值,expire_date是过期时间。真正的数据是存在后台的,所以我们说session是存在于服务器端的会话技术。
在这里插入图片描述

下次前端访问后端的时候,它会把sessionid传过来,sessionid传过来之后,我们也不会得到sessionid,你得到的还是我们刚刚添加的userid,在内部它会自动查数据库,并且把对应的userid的值取出来,所以存也好,取也好,django都做好了。

注销之后,数据库里的session_key那条记录也会被删掉。

在这里插入图片描述

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

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

相关文章

Navicat for Mysql 显示 emoji 表情符号乱码问题

系统环境&#xff1a; 操作系统&#xff1a;MAC OS 10.11.6 MySQL&#xff1a;Server version: 5.6.21 MySQL Community Server (GPL) Navicat for MySQL: version 9.3.1 - standard 1、问题发现 在客户端执行用户注册&#xff0c;用户名支持 emoji 表情&#xff0c;注册完成后…

【⑬MySQL | 数据类型(一)】简介 | 整数 | 浮点 | 定点类型

前言 ✨欢迎来到小K的MySQL专栏&#xff0c;本节将为大家带来MySQL数据类型简介 | 整数 | 浮点 | 定点类型的分享✨ 目录 前言0.数据类型简介1 整数类型2 浮点类型3 定点类型4 日期/时间类型总结 0.数据类型简介 数据类型&#xff08;data_type&#xff09;是指系统中所允许的…

musl libc ldso 动态加载研究笔记:动态库的搜索路径

前言 在手动设置动态库的存放路径的情况下&#xff0c;发现 musl ldso 依旧可以加载位于 /lib 目录下的 动态共享库 动态库的存放路径或者说搜索路径&#xff0c;是否可以手动配置&#xff1f;比如 Linux 上 有个配置文件可以配置&#xff0c;可以改变 动态库的搜索次序&#…

花了4天,做了一个公司的管理系统,只需几个步骤

一、背景 我是企业的管理人员&#xff0c;公司发展到现阶段&#xff0c;感觉进入到了瓶颈期&#xff0c;每个员工的工作都已经饱和&#xff0c;很难再挤出时间做其它的事情&#xff0c;需要一款合适的管理软件来协作我们的工作。 本来打算买一套管理软件就行了&#xff0c;现实…

jupyter notebook 插件nbextensions的安装

安装步骤&#xff1a; 1、打开 jupyter notebook&#xff0c;新建一个 python 文件&#xff1b; 2、 分别输入以下代码&#xff0c;然后运行&#xff0c;出现 warning 不影响使用&#xff0c;如果出现 errors&#xff0c;则说明下载有问题&#xff1a; !python -m pip install…

Elasticsearch(十四)搜索---搜索匹配功能⑤--全文搜索

一、前言 不同于之前的term。terms等结构化查询&#xff0c;全文搜索首先对查询词进行分析&#xff0c;然后根据查询词的分词结果构建查询。这里所说的全文指的是文本类型数据&#xff08;text类型&#xff09;,默认的数据形式是人类的自然语言&#xff0c;如对话内容、图书名…

本地生活服务平台加盟哪家公司好?

本地生活的竞争从年初的火热到现在&#xff0c;已经进入了下半场&#xff0c;随着优胜劣汰的筛选&#xff0c;那么直到现在&#xff0c;想做本地生活服务平台加盟&#xff0c;哪家公司比较好呢&#xff0c;应该如何选择呢&#xff1f; 首先我们得弄懂&#xff0c;我们加盟本地…

c#设计模式-结构型模式 之 外观模式

概述 外观模式&#xff08;Facade Pattern&#xff09;又名门面模式&#xff0c;隐藏系统的复杂性&#xff0c;并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式&#xff0c;它向现有的系统添加一个接口&#xff0c;来隐藏系统的复杂性。该模式…

命令行一键启动和关闭java应用

背景 近来在搞springcloud微服务&#xff0c;有服务的注册和发现&#xff0c;即nacos。有网关服务&#xff0c;即spring-gateway。有认证中心服务。还有用户中心服务&#xff0c;文件中心服务&#xff0c;springboot admin等等。部署的时候&#xff0c;这么多服务&#xff0c;…

2023-8-23 KMP字符串

题目链接&#xff1a;KMP字符串 #include <iostream>using namespace std;const int N 100010, M 1000010;int n, m; char p[N], s[M]; int ne[N];int main() {cin >> n >> p 1 >> m >> s 1;// 求ne&#xff0c;也就是求next数组的过程for…

司徒理财:8.23晚间黄金多空走势分析及操作策略

黄金走势分析&#xff1a;      黄金下跌遇阻&#xff0c;短线开启震荡调整走势&#xff0c;但跌势依旧没有改变&#xff0c;没有突破1906压力前&#xff0c;还是偏空走势&#xff0c;反弹继续干空。趋势行情&#xff0c;不要轻言翻转&#xff01;即便下跌结束&#xff0c;…

从零开始搭建公司后台技术栈

整个后台技术栈我的理解包括 4 个层面的内容&#xff1a; 语言&#xff1a;用了哪些开发语言&#xff0c;如&#xff1a;C/Java/Go/PHP/Python/Ruby 等等&#xff1b;组件&#xff1a;用了哪些组件&#xff0c;如&#xff1a;MQ 组件&#xff0c;数据库组件等等&#xff1b;流…

网络安全(黑客)自学,看这篇就够了!

前言 想自学网络安全&#xff08;黑客技术&#xff09;首先你得了解什么是网络安全&#xff01;什么是黑客&#xff01; 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、…

Spring缓存深入解析:@Cacheable的使用详解

摘要&#xff1a;在本文中&#xff0c;我们将深入研究Spring框架中的Cacheable注解。我们会通过详细的Java示例&#xff0c;探讨如何使用这个功能强大的注解来提升应用程序性能。 一、什么是缓存&#xff1f; 在计算机科学中&#xff0c;缓存是一种存储技术&#xff0c;用于保…

入门超值型32位单片机MM32G0001开发板

灵动微入门级超值型MM32G0001系列MCU。采用48MHz ArmCortex-M0内核&#xff0c;提供16KB Flash和2KB SRAM&#xff0c;并提供丰富的外设资源。适用于多种多样的入门级32位MCU市场&#xff0c;可覆盖广泛的8/16位MCU升级需求。MM32G0001在各种温度范围内的闪存擦写寿命与数据保存…

OzCode v4.0 for VS2022 Crack

在 Datadog&#xff0c;我们认为了解生产环境对于构建更好的软件至关重要&#xff0c;尤其是在现代环境变得越来越复杂的情况下。生产中出现的错误通常很难在本地重现&#xff0c;OzCode 这使得开发人员只能猜测出了什么问题。为了解决这个问题&#xff0c;团队需要像本地环境一…

kaggle推荐系统比赛top方案汇总【附baseline代码】

推荐系统可以很好地解决信息过载以及信息不足等问题&#xff0c;广泛应用与电商、金融、新闻咨询、社交、旅游等行业&#xff0c;其中最典型并具有良好的发展和应用前景的领域就是电子商务领域。 在学术界&#xff0c;推荐系统同样是热门的研究方向&#xff0c;在各大顶会中的…

skynet环境搭建

一、系统环境&#xff1a;win10 二、基础软件下载&#xff1a; 1、VirtualBox虚拟机软件 下载地址&#xff1a;Oracle VM VirtualBox 其实常用的虚拟机软件是VMWare&#xff0c;VirtualBox&#xff0c;它轻量、开源免费&#xff0c;学习使用够用。 2、Ubuntu系统镜像 下载…

堆叠聚合模型是处理非平衡数据的理想算法

堆叠聚合模型是处理非平衡数据的理想算法 堆叠聚合模型的设计是通过训练多个模型&#xff0c;然后使用原模型&#xff0c;将多个模型的输出结果整合在一起以实现更准确的预测。这叠聚合模型在多个临床场景上都表现出优于单一模型的效能[1]。是构建临床预测模型过程中值得考察的…

听GPT 讲Alertmanager源代码--api

在Alertmanager项目中&#xff0c;api目录承担了与Alertmanager的API相关的功能和实现。下面是api目录中一些主要文件和作用的详细解释&#xff1a; api.go: 这个文件定义了Alertmanager的API接口&#xff0c;包括路由和处理API请求的函数。它定义了与Alertmanager交互的各种AP…