目录

cookie与session

为什么会有cookie和session

由于HTTP协议是无状态的,无法记住用户是谁,这样我们在每一次登陆的时候,都要重新输入密码,甚至如果不设置cookie,网页可能都请求不了

cookie

保存在客户端浏览器上的键值对

服务端设置在客户端浏览器上的键值对,也就意味着浏览器其实可以拒绝服务端的命令。默认情况下,浏览器都是直接让服务端设置键值对的

在操作开始之前我们需要对三板斧进行变形

obj1 = HttpResponse()
return obj1
obj2 = render()
return obj2
obj3 = redirect()
return obj3

设置cookie

obj1.set_cookie()

获取cookie

request.COOKIES.get()

删除cookie

obj1.delete_cookie()

实例:cookie版登录校验

直接上代码:

def login(request):
# print(request.path_info) # 只拿url 不拿get请求携带的额外参数
# print(request.get_full_path()) # 都拿 if request.method == "POST":
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'yjy' and password == '123':
old_path = request.GET.get('next')
if old_path:
# 保存用户登录状态
obj = redirect(old_path)
else:
obj = redirect('/home/')
obj.set_cookie('name', 'yjy') # 让客户端浏览器 记录一个键值对
# obj.set_cookie('name','jason',max_age=5) # 让客户端浏览器 记录一个键值对
return obj
return render(request, 'login.html') from functools import wraps #装饰器修复技术
def login_auth(func):
@wraps(func)
def inner(request, *args, **kwargs):
if request.COOKIES.get('name'):
res = func(request, *args, **kwargs)
return res
else:
target_url = request.path_info
return redirect('/login/?next=%s' % target_url)
return inner @login_auth
def home(request):
# 校验用户是否登录
# if request.COOKIES.get('name'):
# return HttpResponse('我是主页 只有登录了才能看')
# return redirect('/login/')
return HttpResponse('我是主页 只有登录了才能看') @login_auth
def index(request):
return HttpResponse('我是index页面 也需要用户登录之后才能看') @login_auth
def xxx(request):
return HttpResponse('xxx页面 也是需要登录了之后才能看') @login_auth
def logout(request):
obj = redirect('/login/')
obj.delete_cookie('name') #注销之后删除cookie
return obj

session

保存在服务器上的键值对

django session默认的过期时间是14天

设置session

 request.session['key'] = value   #仅仅只会在内存产生一个缓存

三步骤:

  • django内部自动生成了随机的字符串
  • 在django_session表中存入数据

session_key session_data date

随机字符串1 数据1 ...

随机字符串2 数据2 ...

随机字符串3 数据3 ...

  • 将产生的随机字符串发送给浏览器 让浏览器保存到cookie中(sessionid:随机字符串)
def set_session(request):
request.session['username'] = 'yjy'
request.session.set_expiry(value=0) #session在关闭浏览器后消失
return HttpResponse("设置session")

获取session

request.session..get('key')

三步骤:

  • 浏览器发送cookie到django后端之后 django会自动获取到cookie值
  • 拿着随机字符串去django_session表中比对 是否有对应的数据
  • 如果比对上了 就讲随机字符串所对应的数据 取出赋值给request.session,如果对不上 那么request.session就是空

session表中的一条记录针对一个浏览器,同一台电脑上,不同的浏览器来,才会有不同的记录

def get_session(request):
print(request.session.get('username'))
return HttpResponse('获取session')

删除session

delete:删除服务端的

request.session.delete()

flush:浏览器和服务端全部删除

request.session.flush()
def delete_session(request):
# request.session.delete() #删除服务端的session request.session.flush() #两个端的session都会删除
return HttpResponse("删除session")

session也可以设置超时时间

request.session.set_expiry(value)
  • value为整数,session会在数秒后消失(以秒为单位)
  • value为 datatime或者timedelta时, session会在这个时间后消失
  • value为0,session会在关闭浏览器后消失
  • value为None,session会依赖全局session失效策略

实例:session版登录校验

后端

from django.shortcuts import render, HttpResponse, redirect

# Create your views here.
def login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password') if username == "yjy" and password == "123456":
# 设置session值
request.session['username'] = username
# 获取跳到登陆之前的url
next_url = request.GET.get("next")
if next_url:
return redirect(next_url)
else:
return redirect('/index/')
return render(request, "login.html") # 装饰器
from functools import wraps def check_login(func):
@wraps(func)
def inner(request, *args, **kwargs):
next_url = request.get_full_path()
print(next_url)
if request.session.get('username'):
return func(request, *args, **kwargs)
else:
return redirect(f"/login/?next={next_url}")
#http://127.0.0.1:8000/login/?username=yjy&password=123456
return inner @check_login
def index(request):
# request.session.get("username", None)
return HttpResponse('我是index页面 需要用户登录之后才能看')

前端:

<form action="" method="post">
{% csrf_token %}
<p>username:<input type="text" name="username"></p>
<p>password:<input type="text" name="password"></p>
<button><input type="submit"></button>
</form>

最终结果是这样子的

提交数据之后的显示

数据库中session的显示

django中间件

应用场景

用户访问频率限制

用户是否是黑名单 白名单

所有用户登录校验

只要是涉及到网址全局的功能 中间件是不二之选

自定义方法

我们先要做好相应的数据准备

1.新建一个文件夹 里面新建一个任意名称的py文件

里面写类 固定继承

from django.utils.deprecation import MiddlewareMixin
class MyMiddle(MiddlewareMixin):
...

2.去配置文件注册到中间件配置中

需要手写字符串的路径

 'app01.mymiddleware.myaabb.MyMiddle1'
'app02.mymiddleware.myaabb.MyMiddle2'

process_request:

请求来的时候 会从上往下依次经过每一个中间件里面process_request,一旦里面返回了HttpResponse对象那么就不再往后执行了 会执行同一级别的process_response

def process_request(self,request):
print('我是第一个自定义中间件里面的process_request方法')
return HttpResponse("我是第一个自定义中间件里面的HttpResponse对象返回值") # 直接原地返回

process_response:

响应走的时候 会从下往上依次经过每一个中间件里面的process_response

def process_response(self,request,response):  # response就是要返回给用户的数据
print("我是第一个自定义中间件里面的process_response方法")
return response #只要有response参数,就必须给他返回

process_view:

路由匹配成功之后,执行视图函数之前触发

process_exception:

当视图函数出现异常(bug)的时候自动触发

process_template_response:

当视图函数执行完毕之后并且返回的对象中含有render方法的情况下才会触发

django请求生命周期流程图

中间件之前端操作

form表单

写form表单之前只需要加上{% csrf_token %}

ajax

第一种: 自己再页面上先通过{% csrf_token %}获取到随机字符串 然后利用标签查找

data:{'username':'jason','csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val()},

第二种:

data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},

第三种:拷贝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 protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
} $.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});

跨站请求伪造(csrf)

原理:

你写的form表单中 用户的用户名 密码都会真实的提交给银行后台

但是收款人的账户却不是用户填的 你暴露给用户的是一个没有name属性的input框

你自己提前写好了一个隐藏的带有name和value的input框

钓鱼网站实例

后端

def transfer(request):
if request.method == 'POST':
username = request.POST.get('username')
target_user = request.POST.get('target_user')
money = request.POST.get('money')
print('%s 给 %s转了%s钱' % (username, target_user, money))
return render(request, 'transfer.html')

正儿八经网站前端

<form action="" method="post">
<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>

钓鱼网站前端

<form action="http://127.0.0.1:8000/transfer/" method="post">
<p>username:<input type="text" name="username"></p>
<p>targer_user:<input type="text"></p>
<p><input type="text" name="target_user" value="jason" style="display: none"></p>
<p>money:<input type="text" name="money"></p>
<input type="submit">
</form>

防钓鱼网站策略

只要是用户想要提交post请求的页面 我在返回给用户的时候就提前设置好一个随机字符串当用户提交post请求的时候 我会自动先取查找是否有该随机字符串

如果有 正常提交,如果没有 直接报403

以上仅仅是一个思路,还是需要我们用代码去实现,具体的实现方法就是在里面注入中间件。

CBV加装饰器

先要导入模块

from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django.utils.decorators import method_decorator

csrf_exempt 两种装饰方式

第一种

@method_decorator(csrf_exempt,name='dispatch')
class MyCsrf(View):

第二种

@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request,*args,**kwargs)
def get(self,request):
return HttpResponse('hahaha')

其他装饰器 三种装饰方式

第一种

@method_decorator(csrf_protect,name='post')
class MyCsrf(View):

第二种

@method_decorator(csrf_protect)
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request,*args,**kwargs)
def get(self,request):
return HttpResponse('hahaha')

第三种

@method_decorator(csrf_protect)
def post(self,request):
return HttpResponse('post'

每日面试题

python2和python3的区别(至少写三个)

'''
py2:
>>> print("hello", "world")
('hello', 'world')
py3:
>>> print("hello", "world")
hello world py2:input_raw()
py3:input() 1/2的结果
py2:返回0
py3:返回0.5 py2:默认编码ascii
py3:默认编码utf-8 字符串
py2:unicode类型表示字符串序列,str类型表示字节序列
py3::str类型表示字符串序列,byte类型表示字节序列 py2:函数用关键字global声明某个变量为全局变量,但是在嵌套函数中,想要给一个变量声明为非局部变量是没法实
现的。
py3:新增了关键字nonlocal,使得非局部变量成为可能 py2:
int() # 整型
long() # 长整型
py3:没有long类型,只有int类型 py2:xrange 用法与 range 完全相同,所不同的是生成的不是一个list对象,而是一个生成器。
py3:将以前的range取消了,而将xrange重新命名成了range!所以我们现在看到的range其实本质还是xrange~。 py2: iteritems() 用于返回本身字典列表操作后的迭代器【Returns an iterator on allitems(key/value pairs) 】,不占用额外的内存。
py3: iteritems()方法已经废除了。在3.x里用 items()替换iteritems() ,可以用于 for 来循环遍历
'''

什么是可变,什么是不可变

'''
可变不可变指的是内存中的值是否可以被改变,
可变:值得改变不会引起内存地址的改变
不可变:值得改变会引起内存地址的改变
不可变类型有数值、字符串、元组;
可变类型则是可以改变,主要有列表、字典。
'''

m=10,n=5,互换值(至少两种方式)

'''
t = m #t=10
m = n #m=5
n = t #n=10 m,n = n,m #交叉赋值
'''

Django之cookie与session、中间件的更多相关文章

  1. Django之Cookie、Session、CSRF、Admin

    Django之Cookie.Session.CSRF.Admin   Cookie 1.获取Cookie: 1 2 3 4 5 6 request.COOKIES['key'] request.get ...

  2. [py][mx]django的cookie和session操作-7天免登录

    浏览器同源策略(same-origin policy) csrf攻击防御核心点总结 django的cookie和session操作-7天免登录 flask操作cookie&django的see ...

  3. Django基础cookie和session

    Django基础cookie和session 1.会话跟踪 ​ 什么是会话!可以把会话理解为客户端与服务器之间的一次会晤,在一次会晤中可能会包含多次请求和响应.例如给10086打个电话,你就是客户端, ...

  4. django 2 ORM操作 ORM进阶 cookie和session 中间件

    ORM操作 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过使用描述 ...

  5. django的cookie和session以及内置信号、缓存

    cookie和session cookie和session的作用: cookie和session都记录了客户端的某种状态,用来跟踪用户访问网站的整个回话.两者最大的区别是cookie的信息是存放在浏览 ...

  6. Django中cookie和session

    cookie Cookie的由来 大家都知道HTTP协议是无状态的. 无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不 ...

  7. 第4天:Django的cookie和session

    Cookie Session Cookie 浏览器请求服务器是无状态的,它的每一次请求对于服务器来说都是新的,服务器默认不会保存用户的状态数据.但很多时候,服务器需要保存用户的一些状态数据,比如用户是 ...

  8. Django之Cookie、Session和自定义分页

    cookie Cookie的由来 大家都知道HTTP协议是无状态的. 无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不 ...

  9. django的cookie和session以及缓存

    cookie和session cookie和session的作用: cookie和session都记录了客户端的某种状态,用来跟踪用户访问网站的整个回话.两者最大的区别是cookie的信息是存放在浏览 ...

随机推荐

  1. .bat文件和Jar包的生成及运行

    .bat文件和Jar包的生成及运行 1.Jar包简单介绍 Jar包是Java中所特有的一种压缩文档,有点类似于zip包,区别在于Jar包中有一个META-INF\MANIFEST.MF文件(在生成Ja ...

  2. kafka使用

    0: ./sbt update ./sbt package ./sbt assembly-package-dependency 1: 启动ZK: 通过kafka的命令启动:bin/zookeeper- ...

  3. yii2系统定义的常用路径别名

    @yii 表示Yii框架所在的目录,也是 yii\BaseYii 类文件所在的位置: @app 表示正在运行的应用的根目录,一般是 digpage.com/frontend :物理路径 @vendor ...

  4. js设置datagriad的行移动

    //                    ,//                formatter: function(value,row,index){//                    ...

  5. javascript中错误使用var造成undefined

    在javascript中依据变量作用的范围不同分为局部变量和全局变量,直接定义的变量是全局变量,全局变量能够被全部的脚本訪问:在函数中定义的变量是局部变量,局部变量仅仅在函数内有效. 假设全局变量和局 ...

  6. java四种创建对象的方法

    1.用new语句创建对象,这是最常见的创建对象的方法.   2.运用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance ...

  7. 正式学习React (七) react-router 源码分析

    学习react已经有10来天了,对于react redux react-redux 的使用流程和原理,也已经有一定的了解,在我上一篇的实战项目里,我用到了react-route,其实对它还只是 停留在 ...

  8. cocos2d-x游戏开发系列教程-超级玛丽03-main函数

    代码下载链接 http://download.csdn.net/detail/yincheng01/6864893 解压密码:c.itcast.cn main函数内容 #include "m ...

  9. 我的 MarkDown 学习笔记

    MarkDown 一种用于写作的轻量级[标记语言].它用简洁的语法代替排版,而不像一般的文字处理软件 Word 或者 Pages 有大量的排版.字体设置等. 如果你对文章的样式没有太多要求,只注重写文 ...

  10. Unity渲染优化中文翻译(三)——GPU的优化策略

    如果游戏的渲染瓶颈来自于GPU 首要任务就是找出造成GPU瓶颈的因素所在,通常GPU的性能受到像素分辨率的影响,特别是在移动客户端的游戏,但是内存带宽和顶点计算的影响也需要注意.这些因素的影响都需要实 ...