自动化运维Python系列之Django CSRF跨站请求伪造、中间件

CSRF

CSRF,跨站请求伪造是一种挟持用户在当前已登陆的web站点应用程序上执行非本意的操作攻击方法,简单地说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并执行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品)。

Django的CSRF中间件验证就可以有效地杜绝此类恶意攻击,原理就是Django在内部会对通过验证请求的客户端再做一次加密验证,该加密方式只有Django自己知道,客户端即使携带session反解密CSRF不成功也会拒绝访问;这是Django生命请求周期中必经的一步,由此我们也可以引出中间件的概念及一般的自定义中间件使用方法

在setting中开启CSRF验证

开启后浏览器携带的CSRF验证信息

由于开启了全局CSRF验证,以后我们每提交的一个页面POST请求,Django都会要求验证,所以我们必须在页面加载该配置信息,有2种方式

1)前端页面直接提交

<form action="/login/" method="POST">
    // 在from表单中添加模版信息
    {% csrf_token %}
    <input type="text" name="user" />
    <input type="text" name="pwd" />
    <input type="submit" value="提交" />
</form>

2)ajax提交

$(function(){
    // 这是ajax全局事件 发ajax请求之前做操作
    $.ajaxSetup({
        beforeSend: function(xhr,settings){
            xhr.setRequestHeader(‘X-CSRFtoken‘, $.cookie(‘csrftoken‘));
        }
    });
  
    $(‘#btn1‘).click(function () {
        $.ajax({
            url: ‘/login/‘,
            type:"GET",
            data: {‘user‘: ‘root‘, ‘pwd‘: ‘123‘},
            // 在请求头中加入CSRFtoken 如果上面已经设置了ajax全局绑定 就可以省略
            // headers: {‘X-CSRFtoken‘: $.cookie(‘csrftoken‘)},
            success:function(arg){
            }
        })
    });
})

后台我们可以通过X-CSRFtoken获取

# print(settings.CSRF_HEADER_NAME)
# HTTP_X_CSRFTOKEN
# X-CSRFtoken

对于在中间件中启用CSRF后,意味着全局view函数都会被要求验证,如果有需求某几个页面views不需要,可以添加下面的装饰器

// 取消CSRF验证保护
@csrf_exempt
def index(request):
  
// 单独开启CSRF验证保护
@csrf_protect
def index(request):

中间件

Django中的中间件,其实是一个类,在请求到来和结束后,Django会根据自己的规则在合适的时机执行中间件中相应的方法,如上面图一我们看到的MIDDLEWARE里面的就是Django中已经注册在使用的中间件

1)自定义中间件

在中间件中我们可以自定义5种方法

// 1)接受请求方法
process_request(self,request)
// 2)接受视图方法
process_view(self, request, callback, callback_args, callback_kwargs)
// 3)判断返回函数是否有render方法
process_template_response(self,request,response)
// 4)异常处理方法
process_exception(self, request, exception)
// 5)回复请求
process_response(self, request, response)

在app同级目录建立中间件目录Middle,新建中间件文件m1.py

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
// 定义class 需要继承MiddlewareMixin
class Row1(MiddlewareMixin):
    def process_request(self,request):
        print(‘request_row_1‘)
 
    def process_view(self, request, view_func, view_func_args, view_func_kwargs):
        print(‘view_row_1‘)
 
    def process_response(self, request, response):
        print(‘process_row_1‘)
        return response
 
class Row2(MiddlewareMixin):
    def process_request(self,request):
        print(‘request_row_2‘)
 
    def process_view(self, request, view_func, view_func_args, view_func_kwargs):
        print(‘view_row_2‘)
 
    def process_response(self, request, response):
        print(‘process_row_2‘)
        return response

在setting中注册中间件,注意我们放置位置,运行程序我们看看Django中间件的运行顺序是什么

路由URL配置

urlpatterns = [
    url(r‘^test/(?P<nid>\d+)$‘, views.test),
]

views视图函数配置

def test(request,nid):
    print(‘view --> ‘)
    return render(request, ‘index.html‘)

运行结果

所以中间件的运行过程其实如下图所示

Django收到用户请求后,会依次被中间件处理,先经过request方法,等执行到最后一个中间件,经过一次路由匹配找到view对应的函数,回头去执行各个中间件的view方法,此时请求携带的额外参数被封装在view_func参数中,最后由服务器端views视图函数返回数据,中间件通过reponse传递消息给用户。

此时中间件的作用就很明显了,可以在请求真正到达服务器后端前做相应操作,比如拦截操作

如果在中间件Row_2中对该请求拦截只需要直接return HttpResponse信息

class Row2(MiddlewareMixin):
    def process_request(self,request):
        print(‘request_row_2‘)
        return HttpResponse(‘row_2_no...‘)

此时我们看中间件执行过程,请求在Row_2中间件处已经被拦截,并没有达到服务器后端views

异常处理

如果服务端views函数发生异常,一般Django会直接报错给用户界面,这样对用户来说不够友好,所以我们可以在中间层面对一些异常拦截,并处理

def test(request,nid):
    print(‘view --> ‘)
    // 模拟处理异常
    i = int(‘abc‘)
    return render(request, ‘index.html‘)

编辑中间件函数

class Row2(MiddlewareMixin):
 
    ...
    // Row_2中加入异常处理
    def process_exception(self, request, exception):
        if isinstance(exception, ValueError):
            return HttpResponse(‘数据处理出现异常。。‘)

界面显示

时间: 03-14

自动化运维Python系列之Django CSRF跨站请求伪造、中间件的相关文章

自动化运维Python系列之Django进阶操作

FBV && CBV FBV.CBV是Django视图路由处理模型,当用户请求送达路由系统URL后,由其转发给视图view来分析并处理 // FBV    function base views  // CBV    class base views 区别就是一个直接用函数驱动,一个用类驱动,两者在使用上存在一些区别 1)FBV URL中根据路由匹配直接转发给视图中的某一个处理函数 urlpatterns = [     url(r'^home/', views.home), ] 视图函数

自动化运维Python系列之Django信号、缓存操作

Django信号 Django内部提供了一种"信号强度"处理机制,简单理解就是当Django在接收到请求后内部做某些特定操作前发出信号,提醒一些接受者或者做操作,这样的好处就是方便程序定制小功能插件,也是对本身框架的一种节藕操作 1)Django的内置信号 Model signals     pre_init                # django的modal执行其构造方法前,自动触发     post_init               # django的modal执行其构

自动化运维Python系列之Django路由系统、Ajax请求

路由系统 路由系统负责分析处理用户请求网址内容,向后视图函数分发处理任务,根据对应的处理函数处理完成后给用户return模板渲染结果:路由系统分类很多,常见的有基本单一路由,正则路由,带额外参数路由,二层三层路由还有通过反射机制来完成的动态路由. 1)单一路由 url(r'^admin/', admin.site.urls) 2)基于正则的路由 url(r'^detail/(\d+)/', views.detail), url(r'^detail2/(?P<p1>\d+)/(?P<x2&

CSRF跨站请求伪造

CSRF(Cross-site request forgery跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用.尽管听起来像跨站脚本(XSS),但它与XSS非常不同,并且攻击方式几乎相左.XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站.与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性. ht

自动化运维Python系列(一)之基础篇

Python介绍 Python是由创始人吉多·范罗苏姆(Guido van Rossum)在1989年圣诞节假期期间,为了打发时间,构思出来的一个新的脚本解释器.由于Guido在开发Python语言过程中,借鉴了很多ABC语言特性,所有后来包括Guido自己也那么认为,Python语言的前身就是ABC语言. Python是一门面向对象的.动态解释型强定义语言:Python崇尚简洁.优美.清晰,是一门优秀的被广泛使用的语言. 在2015年以前,最流行的Python版本还是2.4,但是由于Pytho

自动化运维Python系列之ForeignKey、relationship联表查询

一对多和多对多 数据库表结构设计是程序项目开发前的重要环节,后期数据库操作都是围绕着这个已经设计好的表结构进行,如果表结构设计有问题,整个程序项目就有存在需要整个推翻重构的风险... 数据库表结构除了简单的单表操作以外,还有一对多.多对多等. 一对多 基于SQLAlchemy我们可以先创建如下结构的2张表,然后来看看具体怎样通过外键ForeignKey或者relationship联表操作 创建表 from sqlalchemy.ext.declarative import declarative

自动化运维Python系列(七)之Socket编程

了解知识点TCP\IP 要想理解socket首先得熟悉一下TCP/IP协议族, TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,定义了主机如何连入因特网及数据如何再它们之间传输的标准, 从字面意思来看TCP/IP是TCP和IP协议的合称,但实际上TCP/IP协议是指因特网整个TCP/IP协议族.不同于ISO模型的七个分层,TCP/IP协议参考模型把所有的TCP/IP系列协议归类到四个抽象层中(数据链路层和物理

自动化运维Python系列(四)之装饰器和生成器

装饰器 在理解什么事装饰器之前,我们需要理解:函数也是一个对象,可以赋值给变量,通过变量来调用 def f1():     print('2016') d = f1 d() 输出: 2016 那么装饰器的作用就是在不改变原函数的前提下,调用这些函数,并且为函数增加我们需要的新功能. 我们平时在编写好很多独立函数模块以后,突然需要在每个模块内添加一个功能,比如: def f1():     print('F1') def f2():     print('F2') def f3():     pr

自动化运维Python系列之消息队列RabbitMQ

RabbitMQ RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现.AMQP 的出现其实也是应了广大人民群众的需求,虽然在同步消息通讯的世界里有很多公开标准(如 COBAR的 IIOP ,或者是 SOAP 等),但是在异步消息处理中却不是这样,只有大企业有一些商业实现(如微软的 MSMQ ,IBM 的 Websphere MQ 等),因此,在 2006 年的 6 月,Cisco .Redhat.iMatix 等联合制定了 AMQP 的