大纲

二、session
1、session与cookie对比
2、session基本原理及流程
3、session服务器操作(获取值、设置值、清空值)
4、session通用配置(在配置文件中)
5、session引擎配置(db、cache、file、cookie加密)
三、CSRF
1、csrf原理-form提交及ajax提交
2、csrf全局与局部应用配置
四、中间件生命周期
1、process_request、process_response
下面自己创建一个中间件
2、process_view
3、其他
一、内容回顾

二、session

1、session与cookie对比

Cookie:保存在用户浏览器端的键值对

本地可以修改;如果有敏感信息,可以被看到。

基于cookie做用户验证时,敏感信息不适合放在cookie中
把存储压力放到每个客户端上,对于服务器端压力小了。

Session:保存在服务器端的键值对

服务端:保存键值对{'随机字符串':{……用户信息……}},通过cookie保存随机字符串到客户端上。

使用session前:先执行 python manage.py makemigrations   , python manage.py migrate,因为默认Django session 保存在数据库中的django_session表中。

2、session基本原理及流程

  • session 设置值

    • request.session['is_login'] = True  Django会执行一下操作
   # 生成随机字符串
# 写到用户浏览器cookie
# 保存到session中
# 在随机字符串对应的字典中设置相关内容……
  • session 获取值

    • request.session['is_login']: 执行以下操作
  # 获取当前用户的随机字符串
# 根据随机字符串获取对应信息
  • 使用session前,别忘了先生成数据库   python manage.py migrate

urls.py

    url(r'^login/', views.login),
url(r'^index/', views.index),
url(r'^logout/$', views.logout),

views.py

def login(request):
if request.method == "GET":
return render(request,'login.html')
elif request.method == "POST":
user = request.POST.get('user')
pwd = request.POST.get('pwd')
if user == 'root' and pwd == "":
# session中设置值
# 生成随机字符串
# 写到用户浏览器cookie
# 保存到session中
# 在随机字符串对应的字典中设置相关内容……
request.session['username'] = user
request.session['is_login'] = True
if request.POST.get('rmb',None) == '':
# 超时时间
request.session.set_expiry(10)
return redirect('/index/')
else:
return render(request,'login.html') def index(request):
# 获取当前用户的随机字符串
# 根据随机字符串获取对应信息
if request.session.get('is_login',None):
return HttpResponse(request.session['username'])
else:
return HttpResponse("请登录……") def logout(request):
# del request.session['username']
request.session.clear() # 清除session,注销
return redirect('/login/')

login.html

<body>
<form action="/login/" method="POST">
<input type="text" name="user" />
<input type="text" name="pwd" />
<input type="checkbox" name="rmb" value="1" /> 10秒免登录
<input type="submit" value="提交" />
</form>
</body>>

index.html

<body>
<h1>欢迎登录:{{ username }}, {{ request.session.username }}</h1>
<!---------- 这里不用使用后台模板传值,使用session也能获取到用户名 -------------->
<a href="/logout/">注销</a>
</body>

3、session服务器操作(获取值、设置值、清空值)

 # 获取、设置、删除Session中数据
request.session['k1'] # 获取
request.session.get('k1',None)
request.session['k1'] = 123 # 设置
request.session.setdefault('k1',123) # 存在则不设置
del request.session['k1'] # 删除 # 所有 键、值、键值对
request.session.keys()
request.session.values()
request.session.items()
request.session.iterkeys()
request.session.itervalues()
request.session.iteritems() # 获取用户session的随机字符串
request.session.session_key
# 将所有Session失效日期小于当前日期的数据删除
request.session.clear_expired()
# 检查 用户session的随机字符串 在数据库中是否存在
request.session.exists("session_key")
# 删除当前用户的所有Session数据
request.session.delete("session_key")
request.session.clear() # 比delete用法更简单,注销的时候可以使用 # 设置超时时间 (默认session超时时间是两周)
request.session.set_expiry(value)
# * 如果value是个整数,session会在些秒数后失效。
# * 如果value是个datatime或timedelta,session就会在这个时间后失效。
# * 如果value是0,用户关闭浏览器session就会失效。
# * 如果value是None,session会依赖全局session失效策略。

4、session通用配置(在配置文件中)

settings.py

SESSION_ENGINE = 'django.contrib.sessions.backends.db'  # 引擎(默认)

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,默认修改之后才保存(默认)
# 这个好。settings里设为true,超时时间按照最后一次客户端请求计算,如上按照最后一次请求之后10秒失效。

5、session引擎配置(db、cache、file、cookie加密)

Django中默认支持Session,其内部提供了5种类型的Session供开发者使用:

  • 数据库(默认)
  • 缓存
  • 文件
  • 缓存+数据库
  • 加密cookie
# 数据库Session
SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认) # 缓存Session
SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎
SESSION_CACHE_ALIAS = 'default' # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
# 连接memcache 的配置,缓存部分会提到。不支持redis,连它需要安装插件 # 文件Session
SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎
SESSION_FILE_PATH = os.path.join(BASE_DIR, 'cache') # 放到cache目录下
SESSION_FILE_PATH = None # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()
# 如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T # 缓存+数据库Session
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎 # 加密cookie Session (都放到cookie里面,只是做了加密处理)
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎

三、CSRF

之前提到的xss攻击:网站评论里等允许别人写js的时候,别人进行的恶意操作。csrf类似。

CSRF的防护通常有两种方式,一个是通过Challenge-Response的方式,例如通过Captcha和重新输入密码等方式来验证请求是否伪造,但这会影响用户体验,类似银行付款会采用这样的方式。另一种是通过随机Token的方式,多数Web系统都会采用这种方式,Django也是用的这种。

1、csrf原理-form提交及ajax提交

客户端get请求时,django会生成随机字符串给客户,当客户端提交form表单的时候,如果没有随机字符串,则django不允许,报403错误。

form提交数据需要带随机字符串过去,Ajax提交也需要带着过去。ajax带哪的值?

加上{% csrf_token %}在html form里生成了一个,在也生成了一份。浏览器审查元素 –> Network –> Cookies 里也能找到随机字符串。

所以ajax提交的时候,只需要把cookie里的随机字符串拿到,放到请求头里面发过去就可以了

后台获取随机字符串的key,key是什么值? x-CSRFtoken

login.html

<body>
<!-- form 提交 -->
<form action="/login/" method="POST">
<!-- 生成 csrf 的随机字符串 -->
<!-- {{ csrf_token }} -->
{% csrf_token %} <!--html里会自动生成隐藏input框-->
<input type="text" name="user" />
<input type="text" name="pwd" />
<input type="checkbox" name="rmb" value="1" /> 10秒免登录
<input type="submit" value="提交" />
<input id="btn" type="button" value="Ajax提交" />
</form> <script src="/static/jquery-1.12.4.js"></script>
<script src="/static/jquery.cookie.js"></script>
<script>
$(function(){
// ajax 提交
$.ajaxSetup({ // 对整个页面所有的ajax操作做个配置
beforeSend: function(xhr,settings){ // 发送ajax前的操作
xhr.setRequestHeader('X-CSRFtoken', $.cookie('csrftoken'));
}
}); $('#btn').click(function () {
$.ajax({
url: '/login/',
type:"POST",
data: {'user': 'root', 'pwd': '123'},
// 这种方式加请求头,每个操作都加麻烦一些,所以使用上面的 ajaxSetup 里加
// headers: {'X-CSRFtoken': $.cookie('csrftoken')},
success:function(arg){ }
})
});
})
</script>
</body>

这里ajax提交,在浏览器审查元素、network里看效果。

2、csrf全局与局部应用配置

settings里面,允许csrf验证,那么就是对全局都进行验证。如果个别的方法不需要使用,怎么单一配置?

django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成。而对于django中设置防跨站请求伪造功能有分为全局和局部。

全局:

  中间件 django.middleware.csrf.CsrfViewMiddleware

局部:

  • @csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
  • @csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。

注:from django.views.decorators.csrf import csrf_exempt,csrf_protect

对于ajax中,采用ajaxSetup方式也是全局都加,比如get方式是不需要的,可以如下配置

var csrftoken = $.cookie('csrftoken');

        function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
// settings 会获取到ajax里面的所有配置
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
function Do(){ $.ajax({
url:"/app01/test/",
data:{id:1},
type:'POST',
success:function(data){
console.log(data);
}
}); }

四、中间件生命周期

settings里的 MIDDLEWARE 都是一个一个的中间件。客户端请求,先经过一排一排的中间件到达views,之后再通过中间件返回给客户端。而通过中间件都是调用中间件的某个方法、

1、process_request、process_response

  • process_request:客户端请求,经过中间件的方法
  • process_response:返回客户端,经过中间件的方法

下面自己创建一个中间件

随便创建一个目录middle,

middle/m.py

from django.utils.deprecation import MiddlewareMixin

class Row1(MiddlewareMixin):
def process_request(self, request):
print("中间件1")
def process_response(self, request, response):
print("中间件1返回")
return response
# 参数里的 response :就是views里面返回的值,所以要继续返回一下,否则客户端收不到数据
from django.shortcuts import HttpResponse
class Row2(MiddlewareMixin):
def process_request(self, request):
print("中间件2")
# return HttpResponse("禁止你访问")
def process_response(self, request, response):
print("中间件2返回")
return response class Row3(MiddlewareMixin):
def process_request(self, request):
print("中间件3")
def process_response(self, request, response):
print("中间件3返回")
return response

settings.py

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',
'middle.m.Row1',
'middle.m.Row2',
'middle.m.Row3',
]

views.py

def test(request):
print("最终返回信息")
return HttpResponse("OK")

中间件里面的参数request里接受的数据和views里接受的数据是一样的,所以从里面取值可以做相应的判断处理,允不允许数据通过。

比如上面的示例:中间件row2,process_request,里返回数据,则会在同级的process_response里开始返回数据给客户端了。

注意:这是在Django1.10版本才这样的,之前版本:row2返回数据,会在最底部的response开始网上返回数据,这里是row3。

所以中间件是对所有的请求做统一操作,比如数据校验、黑名单过滤

2、process_view

如下:每个中间件类中中加入如下方法:

class Row1(MiddlewareMixin):
def process_request(self, request):
print("中间件1")
def process_view(self, request, view_func, view_func_args, view_func_kwargs):
# view_func 对应 views函数,view_func_args、kwargs 对应 views里的参数、
print("中间件1view")
def process_response(self, request, response):
print("中间件1返回")
return response

请求顺序如下:用户请求 –> 每个中间件的request –> 到达urls路由匹配,匹配成功后 –> 折回每个中间件的view –> views –> 通过response返回

3、其他

def process_exception(self, request, exception):
if isinstance(exception, ValueError):
return HttpResponse("出现异常")
# 异常处理 views函数里出错了,执行这里,如views里 int('lgeng')

views函数如果出现异常,返回会找exception方法,一级一级往上找,如果有处理返回,如果都没有处理就直接返回报错了。

process_template_response(self,request,response)
# 如果views中的函数返回的对象中,具有render方法,执行这个方法。

一、内容回顾

1、基本生命周期

2、URL

    /index/                 index
/list/(\d+) index
/list/(\d+) name='li' index
/list/(\d+) include index

3、views

# 所有内容的原生值
request.body # 所有的post请求,都会放到body里面传过去
request.POST # 从request.body中提取
request.GET # 从request.body中提取
request.FILES
request.xxxx.getlist
# 请求头内容
request.Meta
request.method(POST,GET,PUT)
request.path_info
request.COOKIES
…… # 返回数据 #########
return HttpResponse # 支持返回字符串 和 bytes类型
return render # 渲染页面
return redirect # 跳转 # 返回cookie ##
response = HttpResponse('ok')
response.set_cookie()
return response
# 把cookie,放到响应头里面,客户端浏览器去响应头里面获取。。所以也能设置响应头内容
response['name'] = 'lgeng'

4、Model操作(原生Sql也可以)

# 表内容操作:
models.TB.objects.create()
obj = models.TB(..)
obj.save()
models.TB.objects.all()[7:10] # 切片
models.TB.objects.update()
models.TB.objects.filter()
models.TB.objects.delete
models.TB.objects.values
models.TB.objects.values_list
models.TB.objects.get
models.TB.objects.filter().update()
models.TB.objects.filter().first()
models.TB.objects.filter(**{}).count()
models.TB.objects.filter(双下划线跨表)
models.TB.objects.filter(id__gte=1)
models.TB.objects.exclude(id__lt=1) models.TB.objects.filter(id_in=[1,2,3]) # id__in # 多对多
obj.set
obj.add([1,2,3])
obj.add(1,2,3)
obj.remove([1,2,3])
obj.clear() models.TB.objects.all()
[obj,obj]
obj.fk.name
models.TB.objects.all().order_by('')
models.TB.objects.distinct() ## 跨表操作 ###########
class A:
name ...
# 而A表操作B表,通过表名+‘_set’ --> b_set
class B:
caption ...
fk = ForignKey(A) # B表操作A表,通过 fk.

5、模板语言

# 基本操作
def func(request):
return render(request,'index.html',{'val':[1,2,3]})
# index.html 里
<h1>{{ val.0 }}</h1>
# 继承
extends "layout.html"
# include
组件
# simpli_tag, filter

转载请务必保留此出处:http://www.cnblogs.com/lgeng/articles/7365891.html

<!-- END  -->

《版本说明》: 本文转自 -- http://blog.csdn.net/fgf00/article/details/5429199



Django(六)Session、CSRF、中间件的更多相关文章

  1. Django之csrf中间件及auth模块使用

    目录 一.基于配置文件的编程思想 1. importlib 模块 2. 配置文件 二.跨站请求伪造(csrf) 1.csrf简介以及由来 2.Django中的csrf中间件如何使用 2.1 普通for ...

  2. django框架进阶-CSRF认证

    ############################################### """ django中csrf的实现机制 #第一步:django第一次响应 ...

  3. 30.Django CSRF 中间件

    CSRF 1.概述 CSRF(Cross Site Request Forgery)跨站点伪造请求,举例来讲,某个恶意的网站上有一个指向你的网站的链接,如果某个用户已经登录到你的网站上了,那么当这个用 ...

  4. 7.Django CSRF 中间件

    CSRF 1.概述 CSRF(Cross Site Request Forgery)跨站点伪造请求,举例来讲,某个恶意的网站上有一个指向你的网站的链接,如果某个用户已经登录到你的网站上了,那么当这个用 ...

  5. django之cookies,session 、中间件及跨站请求伪造

    cookies 和session 为什么会有cookie? ​ 由于http协议是无状态的,即用户访问过后,不留痕迹(状态可以理解为客户端和服务器在某次会话中产生的数据,那无状态的就以为这些数据不会被 ...

  6. Django之cookie与session、中间件

    目录 cookie与session 为什么会有cookie和session cookie 设置cookie 获取cookie 删除cookie 实例:cookie版登录校验 session 设置ses ...

  7. django csrf 中间件

    CSRF和中间件 CSRF使用 说明csrf存在cookie中 全局使用 MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', ...

  8. django模块导入/函数/中间件/MVC和MTV/CSRF

    目录 一:模块导入 二:函数 三:中间件 四:MVC和MTV 五:csrf 一:模块导入 第一种:继承 这里的母版更像是一个架子,子板都是定义的内容(如果多个页面中 ,存在相同的页面:这样我们可以抽到 ...

  9. django—csrf中间件校验流程

    CSRF(跨站请求伪造)是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法. 这利用了web中用户身份验证的一个漏洞:简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求 ...

  10. Django框架-cookie和session以及中间件

    目录 一.cookie 和 session 1.为什么会有这些技术 2. cookie 2.1 Django如何设置cookie 2.2 Django如何获取cookie 2.3 Django如何设置 ...

随机推荐

  1. qt捕获全局windows消息

    qt  如何捕获全屏的鼠标事件,这个帖子上面主要讲述了下嵌入式qt怎么抓取系统级消息,不过从这篇文章中我也看到了希望,有个回复说winEventFilter支持这种方式,然后我就顺着这个线索找到了na ...

  2. PopupWindowMenuUtil【popupwindow样式菜单项列表】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 实现PopupWindow样式的Menu菜单. 效果图 代码分析 使用PopupWindow实现. 列表使用的是Recyclervi ...

  3. springboot~Compiler时开启插件的注解功能

    对于IJ这个IDE工具来说,我们会安装一些插件来帮助我们更好的进行开发,像lombok就是一款不错的插件,使用注解的方式在项目编译时帮助我们生成代码,像getter,setter,tostring等等 ...

  4. 将你的前端应用打包成docker镜像并部署到服务器?仅需一个脚本搞定

    1.前言 前段时间,自己搞了个阿里云的服务器.想自己在上面折腾,但是不想因为自己瞎折腾而污染了现有的环境.毕竟,现在的阿里云已经没有免费的快照服务了.要想还原的话,最简单的办法就是重新装系统.而一旦重 ...

  5. 基于mapreduce实现图的三角形计数

    源代码放在我的github上,想细致了解的可以访问:TriangleCount on github 一.实验要求 1.1 实验背景         图的三角形计数问题是一个基本的图计算问题,是很多复杂 ...

  6. 面向对象之七大基本原则(javaScript)

    1. 前言 2. 单一职责 3. 开闭原则 4. 里氏替换 5. 依赖倒置 6. 接口隔离 7. 迪米特法则 8. 组合聚合复用原则 9. 总结 1. 前言 面向对象编程有自己的特性与原则,如果对于面 ...

  7. Python编程从入门到实践笔记——异常和存储数据

    Python编程从入门到实践笔记——异常和存储数据 #coding=gbk #Python编程从入门到实践笔记——异常和存储数据 #10.3异常 #Python使用被称为异常的特殊对象来管理程序执行期 ...

  8. java--基本数据类型的转换(自动转换)

    概念:Java中,经常可以遇到类型转换的场景,从变量的定义到复制.数值变量的计算到方法的参数传递.基类与派生类间的造型等,随处可见类型转换的身影.Java中的类型转换在Java编码中具有重要的作用.首 ...

  9. Java学习点滴——Class和反射

    基于<Java编程思想>第四版 前言 我们要操作一个类实例对象时,一般都要先知道这个类有哪些方法或者成员变量.反射就是在我们不知道这个类有哪些方法或成员变量时,使用特定方式得到类的这些信息 ...

  10. 折腾Java设计模式之中介者模式

    博文原址:折腾Java设计模式之中介者模式 中介者模式 中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性.这种模式提供了一个中介类,该类通常处理不同类之间的通信,并 ...