Django中间件

由django的生命周期图我们可以看出,django的中间件就类似于django的保安,请求一个相应时要先通过中间件才能到达django后端(url、views、template、models),同样后端进行响应的时候也需要经过中间件才能达到web服务网关。

django的七个中间件

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
# 一些安全设置,比如XSS脚本过滤 'django.contrib.sessions.middleware.SessionMiddleware',
# session支持中间件,加入这个中间件,会在数据库中生成一个django_session的表。 'django.middleware.common.CommonMiddleware',
# 通用中间件,会处理一些URL,比如baidu.com会自动的处理成www.baidu.com。比如/blog/111会处理成/blog/111/自动加上反斜杠。 'django.middleware.csrf.CsrfViewMiddleware',
# 跨域请求伪造中间件。加入这个中间件,在提交表单的时候会必须加入csrf_token,cookie中也会生成一个名叫csrftoken的值,也会在header中加入一个HTTP_X_CSRFTOKEN的值来放置CSRF攻击。 'django.contrib.auth.middleware.AuthenticationMiddleware',
# 用户授权中间件。他会在每个HttpRequest对象到达view之前添加当前登录用户的user属性,也就是你可以在view中通过request访问user。 'django.contrib.messages.middleware.MessageMiddleware',
# 消息中间件。展示一些后台信息给前端页面。如果需要用到消息,还需要在INSTALLED_APPS中添加django.contrib.message才能有效。如果不需要,可以把这两个都删除。 'django.middleware.clickjacking.XFrameOptionsMiddleware',
# 防止通过浏览器页面跨Frame出现clickjacking(欺骗点击)攻击出现。
]

django中间的自定义方法

中间件可以定义五个方法,分别是:(主要的是process_request和process_response)

  • process_request(self,request)
  • process_view(self, request, view_func, view_args, view_kwargs)
  • process_template_response(self,request,response)
  • process_exception(self, request, exception)
  • process_response(self, request, response)

自定义中间件的示例

1.process_request()方法

规律
  1.请求来的时候 会经过每个中间件里面的process_request方法(从上往下)
  2.如果方法里面直接返回了HttpResponse对象 那么会直接返回 不再往下执行
基于该特点就可以做访问频率限制,身份校验,权限校验

2.process_response()方法

规律
  1.必须将response形参返回 因为这个形参指代的就是要返回给前端的数据
  2.响应走的时候 会依次经过每一个中间件里面的process_response方法(从下往上)

3.process_view()方法

  1.在路由匹配成功执行视图函数之前 触发

4.process_exception()方法

  1.当你的视图函数报错时  就会自动执行

5.process_template_response()方法

  1.当你返回的HttpResponse对象中必须包含render属性才会触发

def index(request):
print('我是index视图函数')
def render():
return HttpResponse('什么鬼玩意')
obj = HttpResponse('index')
obj.render = render
return obj

总结:以上方法的返回值可以是None或一个HttpResponse对象,如果是None,则继续按照django定义的规则向后继续执行,如果是HttpResponse对象,则直接将该对象返回给用户。

中间件的proce_request方法是在执行视图函数之前执行的。

当配置多个中间件时,会按照MIDDLEWARE中的注册顺序,也就是列表的索引值,从前到后依次执行的。

不同的中间件之间传递的request都是同一个对象。

如果需要自己写的中间件生效,必须继承MiddlewareMixin,而且要保证在注册时路径不能写错。

csrf跨站请求伪造

关于钓鱼网站的原理,比如说你登录了一个钓鱼网站的页面,和中国银行一模一样的页面,你在哪里进行转账操作,它的转账信息也确实发到了中国银行,你的账户确实也扣钱了,但是唯一不对的时收款人不是你输入的那个人,那是因为它在用户输入框的input上做了手脚,这个input没有设置name属性,而在内部,隐藏的标签里,有一个写好了name和value的input框,这样你只要点击提交,那个value(钓鱼网站受益人的账户)就会和你的转账信息一起发给中国银行。

防止钓鱼网站的思路

网站会给返回给用户的form表单页面 偷偷塞一个随机字符串
请求到来的时候 会先比对随机字符串是否一致 如果不一致 直接拒绝(403)
该随机字符串有以下特点
1.同一个浏览器每一次访问都不一样
2.不同浏览器绝对不会重复

通过{% csrf_token %}来生成随机字符串

1.form表单发送post请求的时候  需要你做得仅仅书写一句话

{% csrf_token %}

2.ajax发送post请求 如何避免csrf校验

1.现在页面上写{% csrf_token %},利用标签查找  获取到该input键值信息
{'username':'jason','csrfmiddlewaretoken':$('[name=csrfmiddlewaretoken]').val()}
$('[name=csrfmiddlewaretoken]').val() 2.直接书写'{{ csrf_token }}'
{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'}
{{ csrf_token }} 3.你可以将该获取随机键值对的方法 写到一个js文件中,之后只需要导入该文件即可
新建一个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的时候,又有几个不需要校验的该如何处理,相反如果你的网站全局不需要校验csrf的时候,又有几个需要校验的功能又该怎么处理。

#先导入模块
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt,csrf_protect

当整个网站都不校验,只想某个功能校验时

# 第一种方式
# @method_decorator(csrf_protect,name='post') # 有效的
class MyView(View):
# 第三种方式
# @method_decorator(csrf_protect)
def dispatch(self, request, *args, **kwargs):
res = super().dispatch(request, *args, **kwargs)
return res def get(self,request):
return HttpResponse('get')
# 第二种方式
# @method_decorator(csrf_protect) # 有效的
def post(self,request):
return HttpResponse('post')

当整个网站都校验,只想某个功能不校验时

#如果是csrf_exempt 只有两种(只能给dispatch装)   特例
@method_decorator(csrf_exempt,name='dispatch') # 第二种可以不校验的方式
class MyView(View):
# @method_decorator(csrf_exempt) # 第一种可以不校验的方式
def dispatch(self, request, *args, **kwargs):
res = super().dispatch(request, *args, **kwargs)
return res def get(self,request):
return HttpResponse('get') def post(self,request):
return HttpResponse('post')

总结:装饰器中只有csrf_exempt是特例,其他的装饰器在给CBV装饰的时候 都可以有三种方式

Auth模块

1、Auth模块是什么

Auth模块是Django自带的用户认证模块:

我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统。此时我们需要实现包括用户注册、用户登录、用户认证、注销、修改密码等功能,这还真是个麻烦的事情呢。

Django作为一个完美主义者的终极框架,当然也会想到用户的这些痛点。它内置了强大的用户认证系统--auth,它默认使用 auth_user 表来存储用户数据。

要注意的时,使用auth模块的话最好用全套。

createsuperuser   #创建超级用户 这个超级用户就可以拥有登陆django admin后台管理的权限

auth模块的功能

    #查询用户
from django.contrib import auth
user_obj = auth.authenticate(username=username,password=password) # 必须要用 因为数据库中的密码字段是密文的 而你获取的用户输入的是明文
#记录用户状态
auth.login(request,user_obj) # 将用户状态记录到session中
#判断用户是否登录
print(request.user.is_authenticated) # 判断用户是否登录 如果是你们用户会返回False
#用户登录之后 获取用户对象
print(request.user) # 如果没有执行auth.login那么拿到的是匿名用户
#校验用户是否登录
from django.contrib.auth.decorators import login_required
@login_required(login_url='/xxx/') # 局部配置
def index(request):
pass # 全局配置 settings文件中
LOGIN_URL = '/xxx/'
#验证密码是否正确
request.user.check_password(old_password)
#修改密码
request.user.set_password(new_password)
request.user.save() # 修改密码的时候 一定要save保存 否则无法生效
#退出登陆
auth.logout(request) # request.session.flush()
#注册用户
# User.objects.create(username =username,password=password) # #创建用户名的时候 千万不要再使用create 了
# User.objects.create_user(username =username,password=password) # 创建普通用户
User.objects.create_superuser(username =username,password=password,email='123@qq.com') # 创建超级用户 邮箱必填

自定义auth_user表

from django.contrib.auth.models import AbstractUser
# Create your models here.
# 第一种 使用一对一关系 不考虑 # 第二种方式 使用类的继承
class Userinfo(AbstractUser):
# 千万不要跟原来表中的字段重复 只能创新
phone = models.BigIntegerField()
avatar = models.CharField(max_length=32) # 一定要在配置文件中 告诉django
# 告诉django orm不再使用auth默认的表 而是使用你自定义的表
AUTH_USER_MODEL = 'app01.Userinfo' # '应用名.类名'
"""
1.执行数据库迁移命令
所有的auth模块功能 全部都基于你创建的表
而不再使用auth_user
"""

 

django中间件和auth模块的更多相关文章

  1. Django CBV加装饰器、Django中间件、auth模块

    一. CBV加装饰器 在视图层中,基于函数的视图叫FBV(function base views),基于类的视图叫CBV(class base views).当需要用到装饰器时,例如之前的基于Cook ...

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

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

  3. Django 2.0 学习(17):Django 用户认证(auth模块)

    Django 用户认证(auth模块) 一.认证登陆 在进行用户登陆验证的时候,如果是自己写代码,就必须要先查询数据库,看用户输入的用户名是否存在于数据库中:如果用户存在于数据库中,然后再验证用户输入 ...

  4. [Django高级之Auth模块]

    [Django高级之Auth模块] auth模块 ←详情点击查看 1.Auth模块是什么 Auth模块是Django自带的用户认证模块: 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统 ...

  5. 中间件和auth模块

    中间件 1.什么是中间件 中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出.因为改变的是全局,所以需要谨慎实用,用 ...

  6. django自关联,auth模块

    一.自关联 写蛮好的一篇博客:https://www.cnblogs.com/Kingfan1993/p/9936541.html 1.一对多关联 1.表内自关联是指表内数据相关联的对象和表是相同字段 ...

  7. 1205 CSRF跨站请求与django中的auth模块使用

    目录 今日内容 昨日回顾 基于配置文件的编程思想 importlib模块 简单代码实现 跨站请求伪造csrf 1. 钓鱼网站 如何实现 模拟该现象的产生 2. 解决问题 解决 {% csrf_toke ...

  8. django中间件 csrf auth认证

    django中间件 能做全局访问频率限制,身份校验,黑名单,白名单 用法: 新建一个文件夹,文件夹新建一个py文件,文件中写如下代码 注意点:你写的类必须继续MiddlewareMixin from ...

  9. Django权限系统auth模块详解

    转自:原文出处 auth模块是Django提供的标准权限管理系统,可以提供用户身份认证, 用户组和权限管理. auth可以和admin模块配合使用, 快速建立网站的管理系统. 在INSTALLED_A ...

随机推荐

  1. Codeforces 1288D - Minimax Problem

    题目大意: 给定n个序列,每个序列元素个数严格相等于m 你需要找到两个序列a[i]和a[j],使其每个对应位置的元素取大后得到b序列  b[k]=max(a[i][k],a[j][k]) 且让b序列中 ...

  2. PID<->Port[转]

    //Netstat -anb #include <Windows.h> #include "Psapi.h" #include <Iprtrmib.h> # ...

  3. log 处理

    保存文件, 并打印到屏幕 import logging def set_log(log_file='log.log'): logging.basicConfig( level = logging.IN ...

  4. virtualbox Ubuntu拒绝root用户ssh远程登录

    http://www.bcty365.com/content-122-6241-1.html

  5. MySQL不能通过127.0.0.1访问

    检查权限都是正确的,最后想到是防火墙的问题 -A INPUT -d 127.0.0.1/32 -j ACCEPT-A INPUT -s 127.0.0.1/32 -j ACCEPT 搞定

  6. bat脚本修改dns(判断系统版本)

    @echo off systeminfo if "%OS 名称%"=="%7%" goto windows7:windows7echo 正在设置本机主DNS , ...

  7. IMX6Q开发板Linux-QT挂载U盘及TF卡

    本文基于:迅为-iMX6开发板Linux-QT挂载U盘及TF卡 如下图所示,qt 启动之后,在超级终端中使用命令“mknod /dev/sda1 b 8 1”创建 U盘的设备节点,如下图所示. 插入 ...

  8. 5)关于CSS和js静态文件引入路径

    (1)参考资料   thinkphp5手册      视图--->输出替换 (2)方法(1)在我们的application中,找到config.php,在里面输入这样的配置: <?php ...

  9. F. Maximum Weight Subset(贪心or树形dp解法)

    题:https://codeforces.com/contest/1249/problem/F 题意:给一颗树,边权为1,节点有点权,问取到一个点集,俩俩之间路径超过k,是点权和最大 思路:贪心地取点 ...

  10. Nesterov方法的python实现

    牛顿动量法,相比于上一篇Momentum,不一样的地方是应用了临时更新 这里用python对其进行简单实现,如下: # coding=utf-8 """ 基于小批量梯度下 ...