一。django中间件简介。

  在django中,有这样的生命周期:

  中间件就是处于wsgiref和urls模块中间,可以拦截所有的请求,其中有7个默认中间件:

  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',
  ]

  其中1,是安全相关的2,是session相关的,4是post提交数据相关,5是登录认证相关。

  中间件中有固定的几个方法,其中也有用户自定义的5个中间件方法。

  django中间件是类似于是django的保安请求的时候需要先经过中间件才能到达django后端响应走的时候也需要经过中间件才能到达web服务网关接口(urls,views,templates,models)。

  而中间件可以用来做这些:网站全局的身份校验,访问频率限制,权限校验...只要是涉及到全局的校验你都可以在中间件中完成 。

  中间件的执行时从上往下,而response则是从下往上。

二。中间件自定义:

  自定义中间件需要导入模块,让类继承自这个模块,这些类所在的模块,就是setting中的配置路径:

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse class MyMdd(MiddlewareMixin):
def process_request(self,request):
print('我是第一个中间件里面的process_request方法') def process_response(self,request,response):
print('我是第一个中间件里面的process_response方法')
return response def process_view(self,request,view_func,view_args,view_kwargs):
print(view_func)
print(view_args)
print(view_kwargs)
print('我是第一个中间件里面的process_view方法') def process_exception(self, request, exception):
print('我是第一个中间件里面的process_exception') def process_template_response(self, request, response):
print('我是第一个中间件里面的process_template_response')
return response

  1.process_request()方法。

  当setting中配置的在文件中的类有该方法时,会在以下情况触发:

  首先,会接受一个request参数。这个就是前端发来的请求。请求来的时候会从上到下执行每一个中间件里的process_request方法。

  如果在里面直接返回了HttpResponse对象,则会直接返回,不会再往下执行。可进行身份校验。

  2.process_response()方法

  当返回前端页面时,会从下往上执行所有中间件中的process_response值。

  每个该方法必须要返回response方法,也必须要接受该方法,如果有的中间件中没有返回该值,则会报错,当没有这个界面。

  3.process_view()

  这个方法再路由匹配成功,执行视图函数之前,的时候会执行并触发。

  其中view_func,代表的是该函数地址。

  4.process_exception()

  当你视图函数报错时,会执行该函数,exception代表的是错误类型。

  5.process_template_response()

  这是一个比较特殊的类型,

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

  如果你的返回的HttpResponse对象中,有render方法的时候,就会走这个中间件。

三。csrf跨站请求伪造。

  在网站获取用户隐秘信息的时候,有一些钓鱼网站就会混在里面,他们的样子一样,但是使用了隐藏表单。

  首先获取正常的页面中一些表单name,再自己做一个一摸一样的,当输入转账用户时,将一个表单隐藏,name设置为正常页面的name,表现出来的表单不设置名字,再将action提交的信息提交到原网站中,这样的网站就会将自己的信息返回。

  如何防止这种钓鱼网站呢?

  网站会给返回给用户的form表单页面 偷偷塞一个随机字符串。

  请求到来的时候 会先比对随机字符串是否一致 如果不一致 直接拒绝(403)。

  这就是中间件所做的事情。

  而防止措施,只要再表单中添加关键字段:

{% csrf_token %}

  就可以在渲染模板的时候,返回一段随机的字符串,name值是:csrfmiddlewaretoken,而当提交表单的时候,这个中间件就会校验这个值。

  当ajax发送值的时候,需要先获取这个值,将他已键值对的方式,放入提交的数据中。

  1.现在页面上写{% csrf_token %},利用标签查找  获取到该input键值信息。

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

  2.直接书写'{{ csrf_token }}'

{'username':'jason','csrfmiddlewaretoken':'{{ 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);
}
}
});

存放的js

  更多细节详见:Djagno官方文档中关于CSRF的内容

四。网站的全局校验装饰器

  当网站全局都需要校验csrf的时候,有几个不需要校验时,可以导入模块:

  1.fbv的校验方式

from django.views.decorators.csrf import csrf_exempt,csrf_protect
@csrf_exempt
def login(request):
return HttpResponse('login') @csrf_protect
def lll(request):
return HttpResponse('lll')

  也就是说,exempt当所有的视图函数都需要校验csrf的时候,某一个函数不需要,就使用exempt方法。

  当所有视图函数都不需要校验csrf的时候,某一个函数需要校验,就使用protect方法。

  2.cbv的校验方法:

  对于csrf_protect。有三种方法可以进行校验:

  该模块是针对给类装饰的。

  from django.utils.decorators import method_decorator  
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只有两种方式:

from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt,csrf_protect
@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')

  也就是说这种方法只能给dispatch装校验,无论是通过类分发还是什么。这是个特例,在其他装饰器的时候,可以通过三种方法进行装饰。

五。用户的登录验证组件。

  在django框架中,执行数据库迁移命令后,会生成很多表,其中有一张auth_user表,这是一张用户信息相关的表格,可以对他执行一些用户的存储:

  1.创建超级用户。

  使用命令行创建一个超级用户:

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

  2.查询用户:

  需要导入模块,其中authenticate就是查询该用户是否存在的函数:

from django.contrib import auth
user_obj = auth.authenticate(username=username,password=password)
# 必须要用 因为数据库中的密码字段是密文的 而你获取的用户输入的是明文

  这个函数会返回一个user_obj对象,这个对象可以进行点操作取出其中的用户名,密码等数据。

  这个函数不支持单用户名查询数据,需要两个一起。

  3.记录用户状态。

auth.login(request,user_obj)  # 将用户状态记录到session中

  auth.login这个方法只要执行就可以在后端任意位置通过request.user获取到当前用户对象。当然也可以通过点操作获取其中的值。如果没有运行该方法,则点出来的是一个匿名对象。

  这句话就相当于request.session['user'] =user_obj

  4.判断用户是否登录。

  鉴于第三条,可以通过判断该对象是否是匿名用户来判断是否登录,但是django给封装了一个方法判断:

print(request.user.is_authenticated)  

# 判断用户是否登录  如果是你们用户会返回False

  这段话就可以判断是否登录。

  5。就以上的函数已经可以做一个装饰器用来判断登录状态了,但是django有自己封装方法:

  局部配置:

from django.contrib.auth.decorators import  login_required
@login_required(login_url='/xxx/') # 局部配置
def index(request):
pass

  其中xxx就是登录的界面地址。

  全局配置:

  可以在setting中配置文件:

LOGIN_URL = '/xxx/'

  这样就可以省略装饰器后面的指定。

  6.验证密码是否正确:

  在修改密码时需要判断老密码是否正确时:

request.user.check_password(old_password)

  返回布尔值。

  7.修改密码。

  在修改密码时需要将用户对象保存:

request.user.set_password(new_password)
request.user.save() # 修改密码的时候 一定要save保存 否则无法生效

  8.退出登录。

  退出登录时,相当于这个操作request.session.flush()。将用户登录装填清除。

auth.logout(request)  # request.session.flush()

  9.用户注册。

  注册时可以使用三种方法,其中第一种没有将密码加密,不建议使用:


from django.contrib.auth.models import User
导入用户表
# 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') # 创建超级用户 邮箱必填

  其中,创建超级会员邮箱是必填的。

  当然,在创建用户的时候需要先校验一下该用户是否存在。这样的操作需要自己的表。

六。自定义用户表

  自定义用户表有两种方法:

  1. 使用一对一关系  不考虑。

  2.使用类的继承。

  首先需要在模型层中导入要继承的类。

from django.contrib.auth.models import AbstractUser

  定义表的时候,不能使用原来表的字段,不能重复,只能创新。

class Userinfo(AbstractUser):
# 千万不要跟原来表中的字段重复 只能创新
phone = models.BigIntegerField()
avatar = models.CharField(max_length=32)

  创建好表后,需要在设置中配置该类,作为user类的替代。

AUTH_USER_MODEL = 'app01.Userinfo'  # '应用名.类名'

  这样的创建后的表,其中就没有auth_user,而是直接变成了你所创建的表。其中包函了auth_user的所有字段,和你添加的外键字段。

  而且,所有的表都基于你创建的表,而不再使用原来的表。

  这个表适用于所有的auth方法。

七。中间件插拔式源码:

  如下。

import settings
import importlib def send_all(content):
for path_str in settings.NOTIFY_LIST: # 1.拿出一个个的字符串 'notify.email.Email'
module_path,class_name = path_str.rsplit('.',maxsplit=1) # 2.从右边开始 按照点切一个 ['notify.email','Email']
module = importlib.import_module(module_path) # from notity import msg,email,wechat
cls = getattr(module,class_name) # 利用反射 一切皆对象的思想 从文件中获取属性或者方法 cls = 一个个的类名
obj = cls() # 类实例化生成对象
obj.send(content) # 对象调方法

  配置文件:

NOTIFY_LIST = [
'notify.email.Email',
'notify.msg.Msg',
# 'notify.wechat.WeChat',
'notify.qq.QQ',
]

  该表结构是:

day59_9_25中间键与登录认证的更多相关文章

  1. Luffy之登录认证以及JWT

    1.用户认证 在前面我们已经完成了,前端登录页面的搭建,以及路由分配,现在我们作关于登录认证部分的东西 Django提供了认证系统.认证系统包含: 用户 权限:二元(是/否)标志指示一个用户是否可以做 ...

  2. spring boot(十四)shiro登录认证与权限管理

    这篇文章我们来学习如何使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公司都会涉及到这方面的需求.在Java领域一般有Spring Security ...

  3. Spring Cloud之路:(七)SpringBoot+Shiro实现登录认证和权限管理

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/sage_wang/article/details/79592269一.Shiro介绍1.Shiro是 ...

  4. 巨蟒python全栈开发django10:ajax&&登录认证

    通过题目进行知识点回顾: 聚合查询 From django.db.models import Avg,Min,Max,F,Q,Count,Sum #查询书籍的平均值 Ret= Models.Book. ...

  5. 记录一下在SpringBoot中实现简单的登录认证

    代码参考博客: https://blog.csdn.net/weixin_37891479/article/details/79527641 在做学校的课设的时候,发现了安全的问题,就不怀好意的用户有 ...

  6. SpringBoot应用篇(二):SpringSecurity实现带验证码的登录认证 附代码

    一.文章简介 本文简要介绍了spring security的基本原理和实现,并基于springboot整合了spring security实现了基于数据库管理的用户的登录和登出,登录过程实现了验证码的 ...

  7. flask中的endpoint、自定义转化器、与djnago中session区别、利用装饰器实现登录认证

    flask路由中的endpoint 与自定义转化器 ''' endpoint主要用于 反向解析, 例如:login函数中配的路由是/login,其中endpoint='lg' 则在其他函数,可以用 u ...

  8. ELK日志系统:Filebeat使用及Kibana如何设置登录认证

    根据elastic上的说法: Filebeat is a lightweight, open source shipper for log file data. As the next-generat ...

  9. Asp.Net MVC3.0网站统计登录认证的在线人数

    Asp.Net MVC3.0网站统计登录认证的在线人数 前言 对于一个网站来说,统计在线人数是一个很重要的工作.平时也发现很多的网站论坛等都有在线人数的显示.对于一个网站如果在线人数很多,用户看到了这 ...

随机推荐

  1. 四、排序算法总结二(归并排序)(C++版本)

    一.什么是归并排序? 归并排序是基于分而治之的思想建立起来的. 所谓的分而治之,也就是将一个数据规模为N的数据集,分解为两个规模大小差不多的数据集(n/2),然而分别处理这两个更小的问题,就相当于解决 ...

  2. 求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222。

    方法一: var num = ""; var nums = []; var a = Number(prompt());//所要拼接的数字 var b = Number(prompt ...

  3. Day2 - Python基础2 列表、字符串、字典、集合、文件、字符编码

    本节内容 列表.元组操作 数字操作 字符串操作 字典操作 集合操作 文件操作 字符编码与转码 1. 列表.元组操作 列表是我们最以后最常用的数据类型之一,通过列表可以对数据实现最方便的存储.修改等操作 ...

  4. Day3 - Python基础3 函数基本、递归函数、内置函数

    本节内容 1. 函数基本语法及特性 2. 参数与局部变量 2.2. 函数变量作用域 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8.内置函数 1. 函数基本语法及 ...

  5. MySQL数据库实战之优酷

    目录 一.项目总结三步骤 二.项目需求分析 三.搭建框架 四.ORM框架分析 五.数据库设计 六.项目中各个功能模块分析 七.项目中遇到的问题及怎么解决的 八.客户端代码框架 8.1 conf 8.1 ...

  6. HTML连载46-浮动元素字围现象、浮动练习

    一.浮动元素的字围现象 div{ float:left; width:100px; height:100px; background-color: red; border:1px solid blac ...

  7. Python爬虫教程-使用chardet

    Spider-03-使用chardet继续学习python爬虫,我们经常出现解码问题,因为所有的页面编码都不统一,我们使用chardet检测页面的编码,尽可能的减少编码问题的出现 网页编码问题解决使用 ...

  8. IT兄弟连 HTML5教程 HTML文档头部元素head

    HTML头部标记是<head>,主要包括页面的一些基本描述语句,以及CSS和JavaScript,一般都可以定义在头部元素中.它用于包含当前文档的有关信息,例如网页标题和关键字等.通常位于 ...

  9. PHP 源码学习 | 变量类型数据结构

    前段时间因为项目需要,研究了一下在 Windows 系统下进行 PHP 扩展的开发,对于 PHP 扩展的开发并不是一件容易的事情(话又说回来了,会者不难,难者不会,关键是自己不会).我当时的需求,主要 ...

  10. Rust开发环境搭建

    1.Rust概述 按照百度百科的说法,Rust是一门系统编程语言 ,专注于安全 ,尤其是并发安全,支持函数式和命令式以及泛型等编程范式的多范式语言.Rust在语法上和C++类似 ,但是设计者想要在保证 ...