文章目录

    • cookie与session
  • Cookie操作
    • session操作
    • CBV如何添加装饰器
    • django中间件
    • 如何自定义中间件
    • csrf跨站请求伪造
    • 如何符合校验
    • csrf相关装饰器
    • 补充知识点
    • 重要思想

cookie与session

'''
发展史1.网站都没有保存用户功能的需求 所有用户访问返回的结果都一样eg:新闻、博客、文字。。2.出现了一些需要保存用户信息的网站eg:淘宝、支付宝、京东。。以登陆功能为例:如果不保存用户登录状态 也就意味着用户每次访问都需要重复的输入用户名和密码当用户第一次登录成功之后 将用户的用户名和密码返回给用户浏览器 让用户浏览器保存在本地,之后每次访问网站的时候浏览器自动将保存在浏览器上的用户名和密码发送给服务器。服务端获取之后自动验证早期这种方式具有非常大的安全隐患优化:当用户登陆成功之后,服务端产生一个随机字符串(在服务端保存数据,用kv键值对的形式),交友客户端浏览器保存随机字符串1:用户1相关信息随机字符串2:用户2相关信息随机字符串3:用户3相关信息之后访问服务端的时候 都带着随机字符串,服务端取数据库中比对是否有对应的随机字符串从而获取到对应的用户信息但是如果拿到了解惑到了该随机字符串,那么你就可以冒充当前用户 其实还是有安全隐患在web领域没有绝对的安全也没有绝对的不安全
'''cookie服务端保存在客户端上的信息都可以称之为cookie表现形式一般都是 k:v键值对(可以有多个) session数据是保存在服务端的 并且它的表现形式一般也是k:v键值对(可以有多个)tokensession虽然数据是保存在服务端的  但是禁不住数据量大服务端不再保存数据登陆成功之后 将一段信息进行加密处理(具体算法只有开发人员知道)将加密之后的结果拼接在信息后面 整体返回给 浏览器保存浏览器下次访问的时候带有该信息 服务端自动切去前面一段信息再次使用自己的加密算法跟浏览器尾部的密文比对总结:1.cookie就是保存在客户端浏览器上的信息2.session就是保存在服务端上的信息3.session是基于cookie工作的(其实大部分的保存用户状态的操作都需要使用到cookie)

Cookie操作

虽然cookes是服务端告诉客户端浏览器需要保存内容
但是客户端可以选择拒绝保存  如果禁止了 那么只要是记录用户状态的网站登陆功能都无法使用了# 视图函数的返回值
return HttpResponse()
return render()
return redirect()obj1 = HttpResponse()
# 操作cookie
return obj1obj2 = render()
# 操作cookie
return obj2obj3 = redirect()
# 操作cookie
return obj3
# 如果你想要操作cookie,你就不得不利用obj对象'''
设置cookieobj.set_cookie(key, value)
获取cookierequest.COOKIES.get(key)
在设置cookie的时候可以添加一个超时时间obj.set_cookie('username', 'zrf666', max_age=5)# 超时时间3秒过期      expires= 3  这个是针对 ie浏览器
删除cookieobj.delete_cookie('username')eg: obj = redirect('/login/')obj.delete_cookie('username')return obj
'''
# 我们完成一个真正的登陆功能# views.pyfrom django.shortcuts import render, HttpResponse, redirect# Create your views here.# 校验用户是否登陆的装饰器
def login_auth(func):def inner(request, *args, **kwargs):www = request.path_info# print(request.get_full_path())if request.COOKIES.get('username'):return func(request, *args, **kwargs)else:print('ssss')return redirect('/login/?www=%s'% www)return innerdef login(request):www = request.GET.get('www')if www == None:www = '/home/'if request.method == "POST":username = request.POST.get('username')password = request.POST.get('password')if username == 'jason' and password == '123':# 保存用户登陆状态obj = redirect(www)# 让浏览器记录cookie记录obj.set_cookie('username', 'zrf666')'''浏览器不单单会帮你存而且后面每次访问你的时候还会带着它过来'''# 跳转到一个用户登陆后才能看到的页面return objreturn render(request, 'login.html')@login_auth
def home(request):# 获取cookie信息 判断你有没有# if request.COOKIES.get('username') == 'zrf666':#     return HttpResponse('home')# 没有登陆就跳转到登陆页面return HttpResponse('hoeme')@login_auth
def index(request):# 获取cookie信息 判断你有没有# if request.COOKIES.get('username') == 'zrf666':#     return HttpResponse('home')# 没有登陆就跳转到登陆页面return HttpResponse('index')@login_auth
def funcc(request):# 获取cookie信息 判断你有没有# if request.COOKIES.get('username') == 'zrf666':#     return HttpResponse('home')# 没有登陆就跳转到登陆页面return HttpResponse('funcc')# urls.pyurlpatterns = [path('admin/', admin.site.urls),re_path(r'^login/', views.login),re_path(r'^home/', views.home),re_path(r'^index/', views.index),re_path(r'^funcc/', views.funcc),
]

session操作

'''
session 数据保存在服务端的, 给客户端返回的是一个随机字符串sessionid:随机字符串1.在默认情况下操作session的时候需要都将哦默认的一张django_session表  可以用数据库迁移命名django默认session的过期时间是14天但是你也可以人为的修改它设置session
request.session['key'] = value获取 session
request.session.get('key')设置过期时间
request.session.set_expiry()括号内可以放四种类型的参数1.整数           多少秒2.日期对象       到指定日期就失效3.0             一旦当前浏览器窗口关闭立刻失效4.不写         就取决于django内部全局session默认的失效时间(14天)清除sessionrequest.session.delete()    # 只删服务端 客户端不删request.session.flush()        # 浏览器和服务端都清空(推荐使用)django_session表中的数据条数是取决于浏览器的同一个计算机上同一个浏览器只会有一条数据生效
'''def set_session(request):request.session['hobby'] = 'girl''''内部发生了哪些事1.django内部会自动帮你随机字符串2.django内部自动将随机字符串和对应的数据存储到django_session表中(这一步不是直接生效的)2.1先在内存中产生操作数据的缓存2.2在响应结果django中间件的时候才操作数据库3.将产生的随机字符串返回给客户端浏览器保存'''return HttpResponse('嘿嘿嘿')def get_session(request):print(request.session.get('hobby'))'''内部发生了哪些事1.自动从浏览器请求中获取sessionid对应的字符串2.拿着该随机字符串去django_session表中查找对应的数据3.如果比对上了 则将数据取出并以字典的形式封装到request.session中如果比对不上 则request.session.get()返回的是None'''利用session实现登陆验证

CBV如何添加装饰器

from django.views import View
from django.utils.decorators import method_decorator
'''
CBV中django不建议你直接给类的方法加装饰器
无论该装饰器能都正常给你 都不建议直接加
'''class MyLogin(View):@method_decorator(login_auth)    # 方式3 :它会直接作用于当前类里面的所有的方法def dispatch(self, request, *args, **kwargs):pass# @method_decorator(login_auth)       # 方式1 直接加def get(self, request):return HttpResponse('get请求')def post(self, request):return HttpResponse('post请求')

django中间件

'''
django中间件是django的门户
1.请求来的时候需要先经过中间件才能达到真正的django后端
2.响应走的时候走的也需要经过中间件才能发送过去django支持程序员 自定义中间件并且暴露给程序员五个可以自定义的方法1.必须掌握process_requestprocess_response2.了解即可process_viewprocess_template_responseprocess_exception
'''

如何自定义中间件

'''
1.在项目名或者应用名下创建一个任意名称的文件夹
2.在该文件夹内创建一个任意名称的py文件
3.在该py文件内需要书写类(这个类必须继承 MiddlewareMixin)然后在这个类里面就可以自定义五个方法了(这五个方法并不是全部都需要书写,用几个写几个)
4.需要将类的路径以字符串的形式注册到配置文件中才能生效
MIDDLEWARE = ['你自己写的中间件的路径1','你自己写的中间件的路径2',
]
'''
'''
1.必须掌握process_request1.请求来的时候会经过每一个中间件里面的process_request方法经过的顺序是按照配置文件中注册的中间件从上往下的顺序依次执行2.如果中间件里面没有定义该方法, 那么直接跳过执行下一个中间件3.如果该方法返回了HttpResponse对象,那么请求不再继续往下执行, 而是直接原路返回(这个功能就是相当于校验失败 不允许访问)process_request方法就是用来做全局相关的所有限制功能process_response1.响应走的时候需要经过每一个中间件里面的process_response方法该方法有两个额外的参数request, response2.该方法必须返回一个HttpResponse对象1.默认返回的就是形参response2.你也可以自己返回自己的3.顺序四行按照配置文件中注册了的中间件从下往上依次经过如果你没有定义的话 直接跳过执行下一个
'''浏览器请求-->---->---中间件1(request)-->-->-----中间件2(requset)-->--->--|                                 |                   || (若有return)                       |(若有return)     |(获取视图函数的return)|                                   |                   |浏览器--<---<--中间件1(response)--<---中间件2(response)---<----<---<------
'''  2.了解即可process_view路由匹配成功之后 执行视图函数之前, 会自动执行中间件里面的process_view方法process_template_response返回的HttpResponse对象有render属性的时候才触发顺序是按照配置文件中注册了的中间件从下往上依次经过process_exception当视图函数中出现异常的清空下触发'''

csrf跨站请求伪造

'''
钓鱼网站我搭建一个跟正规网站一模一样的界面(这个银行)用户不小心进入到了我们的网站, 用户给某个人打钱打钱的操作却确确实实是提交给了中国银行系统, 用户的钱也确实减少了但是不同的是打钱的账户不是用户想打的账户内部本质我们在钓鱼网站的页面 针对对方账户 只给用户一个没有name属性的普通input框然后我们在内部隐藏一个已经写好name和value的input框如何规避上述问题csrf跨站请求伪造校验网站给用户返回一个具有提交数据功能页面的时候给这个页面加一个唯一标识当这个页面朝后端发送post请求的时候 我的后端会先校验唯一标识, 如果唯一标识不对直接拒绝(403 forbbiden)如果成功则正常执行
'''

如何符合校验

# form 表单如何符合校验
在表单内加上 {% csrf_token %}
<form action="" method="post">{% csrf_token %}<p>username: <input type="text" name="username"></p><p>target_user: <input type="text" name="target_user"></p><p>money: <input type="text" name="money"></p><input type="submit"></form># ajax 如何符合校验
// 第一种 利用标签查找 获取页面上的随机字符串{#data:{'username': 'egon', 'csrfmiddlewaretoken': $('[name=csrfmiddlewaretoken]').val()},#}// 第二种 利用模板语法提供的快捷书写{#data:{'username': 'egon', 'csrfmiddlewaretoken': '{{ csrf_token }}' },#}// 第三种 通用方式     直接拷贝js代码并且引用到自己的html页面上即可data:{'username': 'egon'},
  • js 代码
function getCookie(name) {var cookieValue = null;if (document.cookie && document.cookie !== '') {var cookies = document.cookie.split(';');for (var i = 0; i < cookies.length; i++) {var cookie = jQuery.trim(cookies[i]);// Does this cookie string begin with the name we want?if (cookie.substring(0, name.length + 1) === (name + '=')) {cookieValue = decodeURIComponent(cookie.substring(name.length + 1));break;}}}return cookieValue;
}
var csrftoken = getCookie('csrftoken');function csrfSafeMethod(method) {// these HTTP methods do not require CSRF protectionreturn (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}$.ajaxSetup({beforeSend: function (xhr, settings) {if (!csrfSafeMethod(settings.type) && !this.crossDomain) {xhr.setRequestHeader("X-CSRFToken", csrftoken);}}
});

csrf相关装饰器

'''
1.网站整体都不校验csrf, 就单单几个视图函数需要校验csrf_protect: 需要校验csrf
2.网站整体都校验csrf, 就单单几个视图函数不校验csrf_excempt:忽略校验csrf 在FBV上使用一致, 就是普通的装饰器玩法
而在CBV上 只能作用于dispatch方法 '''

补充知识点

# 模块:importlib# from myfile import b
# print(b.name)import importlib
res = 'myfile.b'            # 最小的单位只能到模块名
ret = importlib.import_module(res)
print(ret.name)

重要思想

import settings
import importlib'''
反射就是通过字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动getattr(核心)判断类、对象或者模块中是否有相应的属性或方法。用法:getattr(obj,str,default=None)
判断obj中是否有str属性,有就返回,没有时有传入第三参数就返回第三参数,没有就报错。
'''def send_all(content):for path_str in settings.NOTIFY_LIST:       # 就是一个个的settings里面的字符串module_path, class_name = path_str.rsplit('.', maxsplit=1)# module_path = 'notify.email'  class_name = 'Email'# 1 利用字符串导入模块module = importlib.import_module(module_path)   # == from notify import email# 2 利用反射获取类名            反射:判断类、对象或者模块中是否有相应的属性或方法  有就返回cls = getattr(module, class_name)   # 因为module = from notify import email 相当于是等于emial这个模块 所以这里的意思就是判断emial这个模块中有没有 class_name(Email)这个类 有就返回# 因此 cls这里拿到的是 Email这个类# 3 生成类对象obj = cls()# 4 利用鸭子类型直接调用send方法obj.send(content)

django_day06相关推荐

最新文章

  1. 基于 OpenCV 的人脸追踪
  2. 2019 ICPC Asia Nanjing Regional J.Spy(KM算法O(n^3)板子题)
  3. python3.5安装pygame_安装pygame for Python3.5
  4. 11.15 dmidecode:查询系统硬件信息
  5. 详细解读Spring2.5 +Struts1.3 框架(使用Spring声明式事物管理和springjjdbc模板)
  6. 2014-7-29-阿里电面-第一轮
  7. labiview ni python_LabVIEW到底有哪些优势导致他用户量这么少但是长期不消失?
  8. VirtualBox启动失败,The VM session was aborted.
  9. 17-正交矩阵和Gram-Schmidt正交化
  10. innodb system table
  11. 逆向之制作扫雷外挂——003
  12. excel工具栏隐藏了怎么办_?Excel菜单栏中工具栏突然不见了,怎么办?
  13. npm install 时 WARN No repository field Or No license field
  14. java敏捷开发的落地与实施_20165219 《Java程序设计》实验三(敏捷开发与XP实践)实验报告...
  15. html文本文档加图片格式,以图片格式呈现的文档怎么编辑文字
  16. 如何高效学习.pdf
  17. 【网站】国内最火的10款Java开源项目,都是国人开发,CMS居多
  18. 计算机基础之计算机的前沿技术
  19. python doc 转docx
  20. 前端跨域问题—解决Firefox浏览器显示“已阻止载入混合活动内容”的方法

热门文章

  1. overwrite 的使用区别
  2. (C++模板编程):std::enable_if的使用(下)
  3. 用Go语言 轻松实现插入排序 (Golang经典编程案例)
  4. 在nagios中添加监控主机和服务
  5. 2021年茶艺师(初级)考试试卷及茶艺师(初级)考试申请表
  6. 1亿数字中找出重复次数TopN的问题
  7. yolov5笔记(3)——移动端部署自己的模型(随5.0更新)
  8. 计算机进入怎么解决办法,电脑开机进不了系统怎么办 电脑开机进不了系统解决方法【介绍】...
  9. shell 编程 错误 bash: [: missing `]'
  10. ChatGPT版Bing被调戏到生气发飙,ChatGPT被证实具有人类心智