Django之CBV装饰器,跨站请求伪造,auth认证
CBV加装饰器
基于session实现登录
def login(request):
if request.method == 'POST':
username = request.POST.get('username')
pwd = request.POST.get('password')
if username=='jason' and pwd=='':
request.session['name'] = 'jason' # 这一步是添加session
return redirect('/home/')
return render(request,'login.html')
如果说后面我们遇到了多个页面这些操作,都要实现校验,那么就得用到了装饰器,给类添加装饰器怎么添加?
装饰器
from functools import wraps
def login_auth(func):
@wraps(func)
def inner(request,*args,**kwargs):
if request.session.get('name'):
return func(request,*args,**kwargs)
return redirect('/login')
return inner
类添加装饰器
# 给CBV添加装饰器的方法
'''
1.第一种直接再类上面,必须指定name参数
2.直接再类里面的函数添加
3.重写dispatch方法
4.前端action里面修改路由
'''
# @method_decorator(login_auth,name='get') # 第一种
class Myhome(View):
@method_decorator(login_auth) # 第三种 只要是总路由里面的都可以被装饰
def dispatch(self, request, *args, **kwargs):
super().dispatch(request,*args,**kwargs) # @method_decorator(login_auth) # 第二种
def get(self,request):
return HttpResponse('get') def post(self,request):
return HttpResponse('post')
django中间件
django请求生命周期
django中间件(django门户)
什么是中间件?
官方的说法:中间件是一个用来处理Django的请求和响应的框架级别的钩子。它是一个轻量、低级别的插件系统,用于在全局范围内改变Django的输入和输出。每个中间件组件都负责做一些特定的功能。
但是由于其影响的是全局,所以需要谨慎使用,使用不当会影响性能。
说的直白一点中间件是帮助我们在视图函数执行之前和执行之后都可以做一些额外的操作,它本质上就是一个自定义类,类中定义了几个方法,Django框架会在请求的特定的时间去执行这些方法。
我们一直都在使用中间件,只是没有注意到而已,打开Django项目的Settings.py文件,看到下图的MIDDLEWARE配置项。
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',
]
MIDDLEWARE配置项是一个列表(列表是有序的),列表中是一个个字符串,这些字符串其实是一个个类,也就是一个个中间件。django默认有七个中间件,但是django暴露给用户可以自定义中间件并且里面可以写五种方法
请求来了之后会依次经过每一个门户,才会到urls.py
查看具体方法
class SecurityMiddleware(MiddlewareMixin):
def __init__(self, get_response=None):
self.sts_seconds = settings.SECURE_HSTS_SECONDS
self.sts_include_subdomains = settings.SECURE_HSTS_INCLUDE_SUBDOMAINS
self.sts_preload = settings.SECURE_HSTS_PRELOAD
self.content_type_nosniff = settings.SECURE_CONTENT_TYPE_NOSNIFF
self.xss_filter = settings.SECURE_BROWSER_XSS_FILTER
self.redirect = settings.SECURE_SSL_REDIRECT
self.redirect_host = settings.SECURE_SSL_HOST
self.redirect_exempt = [re.compile(r) for r in settings.SECURE_REDIRECT_EXEMPT]
self.get_response = get_response def process_request(self, request):
path = request.path.lstrip("/")
if (self.redirect and not request.is_secure() and
not any(pattern.search(path)
for pattern in self.redirect_exempt)):
host = self.redirect_host or request.get_host()
return HttpResponsePermanentRedirect(
"https://%s%s" % (host, request.get_full_path())
) def process_response(self, request, response):
if (self.sts_seconds and request.is_secure() and
'strict-transport-security' not in response):
sts_header = "max-age=%s" % self.sts_seconds
if self.sts_include_subdomains:
sts_header = sts_header + "; includeSubDomains"
if self.sts_preload:
sts_header = sts_header + "; preload"
response["strict-transport-security"] = sts_header if self.content_type_nosniff and 'x-content-type-options' not in response:
response["x-content-type-options"] = "nosniff" if self.xss_filter and 'x-xss-protection' not in response:
response["x-xss-protection"] = "1; mode=block" return response
具体代码
ps:
1.请求来的时候会依次执行每一个中间件里面的process_request方法,如果没有直接通过
2.响应走的时候会依次执行每一个中间件里面的process_response方法,如果没有依次通过(后面在补充,有点小坑)
自定义中间件
中间件可以定义五个方法,分别是:(主要的是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)
以上方法的返回值可以是None或一个HttpResponse对象,如果是None,则继续按照django定义的规则向后继续执行,如果是HttpResponse对象,则直接将该对象返回给用户。
自定义一个中间件示例
新建一个任意名字的文件夹,里面新建一个任意名字的文件夹
中间件本质就是含有5个可以修改的内置方法的类,所以自定义的时候需要做的就是先继承一个Django提供的中间件混合父类--MiddlewareMixin
然后记得去settings中配置中间件
请求来了之后会依次往下走
请求走的时候也是从下往上依次执行,但是我们要知道的是,django中说你在当前这个中间件中的process_request中返回了HttpResponse的话,会直接走这个中间件的response方法,直接按照这个中间件的顺序从下往上返回信息。
具体信息查看
注意:如果你的自定义process_response不返回一个return response的话,会直接报错
报错信息是
在自定义的中间件中process_response返回了response
process_request
process_request有一个参数,就是request,这个request和视图函数中的request是一样的(在交给Django后面的路由之前,对这个request对象可以进行一系列的操作)。
由于request对象是一样的,所以我们可以对request对象进行一系列的操作,包括request.变量名=变量值,这样的操作,我们可以在后续的视图函数中通过相同的方式即可获取到我们在中间件中设置的值。
它的返回值可以是None也可以是HttpResponse对象。返回值是None的话,按正常流程继续走,交给下一个中间件处理,如果是HttpResponse对象,Django将不执行视图函数,而将相应对象返回给浏览器。
我们来看看多个中间件时,Django是如何执行其中的process_request方法的。
class Mymiddlewera(MiddlewareMixin):
def process_request(self,request):
print('我是app02中mymiddlewera中第一个自定义的中间件方法请求方法') class Mymiddlewera2(MiddlewareMixin):
def process_request(self,request):
print('我是app02中mymiddlewera中第二个自定义的中间件方法请求方法')
settings中配置
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',
'app02.mymiddlewera.middle.Mymiddlewera', # 自定义中间件1
'app02.mymiddlewera.middle.Mymiddlewera2' # 自定义中间件2
]
通过终端打印,我们发现中间件是自上而下依次执行
然后我们调换一下位置
在打印一下两个自定义中间件中process_request方法中的request参数,会发现它们是同一个对象。
总结:
由此总结一下:
- 中间件的process_request方法是在执行视图函数之前执行的。
- 当配置多个中间件时,会按照MIDDLEWARE中的注册顺序,也就是列表的索引值,从前到后依次执行的。
- 不同中间件之间传递的request都是同一个对象
process_response
多个中间件中的process_response方法是按照MIDDLEWARE中的注册顺序倒序执行的,也就是说第一个中间件的process_request方法首先执行,而它的process_response方法最后执行,最后一个中间件的process_request方法最后一个执行,它的process_response方法是最先执行。
定义process_response方法时,必须给方法传入两个形参,request和response。request就是上述例子中一样的对象,response是视图函数返回的HttpResponse对象(也就是说这是Django后台处理完之后给出一个的一个具体的视图)。该方法的返回值(必须要有返回值)也必须是HttpResponse对象。如果不返回response而返回其他对象,则浏览器不会拿到Django后台给他的视图
通过我们上面的代码和图片演示,我们直接进行总结
总结:
process_response方法是在视图函数之后执行的,并且顺序是从下往上依次执行。
多个中间件中的process_response方法是按照MIDDLEWARE中的注册顺序倒序执行的,也就是说第一个中间件的process_request方法首先执行,而它的process_response方法最后执行,最后一个中间件的process_request方法最后一个执行,它的process_response方法是最先执行。
process_view
process_view(self, request, view_func, view_args, view_kwargs)
该方法有四个参数
request是HttpRequest对象。
view_func是Django即将使用的视图函数。 (它是实际的函数对象,而不是函数的名称作为字符串。)
view_args是将传递给视图的位置参数的列表.
view_kwargs是将传递给视图的关键字参数的字典。 view_args和view_kwargs都不包含第一个视图参数(request)。
Django会在调用视图函数之前调用process_view方法。
它应该返回None或一个HttpResponse对象。 如果返回None,Django将继续处理这个请求,执行任何其他中间件的process_view方法,然后在执行相应的视图。 如果它返回一个HttpResponse对象,那么将不会执行Django的视图函数,而是直接在中间件中掉头,倒叙执行一个个process_response方法,最后返回给浏览器
class Mymiddlewera(MiddlewareMixin):
def process_request(self,request):
print('我是app02中mymiddlewera中第一个自定义的中间件方法请求方法')
print('',request)
# return HttpResponse('好想好好的睡个一夜直到天亮') def process_response(self,requset,response):
print('我是app02中mymiddlewera中第一个自定义的中间件方法响应方法')
return response # 必须将response接收到的数据返回,不然报错 def process_view(self,request,view_func,view_args,view_kwargs):
print('111,你说啥就是啥吧')
print(view_func)
print(view_args)
print(view_kwargs)
终端打印结果
process_view方法是在Django路由系统之后,视图系统之前执行的,执行顺序按照MIDDLEWARE中的注册顺序从前到后顺序执行的
process_exception
process_exception(self, request, exception)
该方法两个参数:
一个HttpRequest对象
一个exception是视图函数异常产生的Exception对象。
这个方法只有在视图函数中出现异常了才执行,它返回的值可以是一个None也可以是一个HttpResponse对象。如果是HttpResponse对象,Django将调用模板和中间件中的process_response方法,并返回给浏览器,否则将默认处理异常。如果返回一个None,则交给下一个中间件的process_exception方法来处理异常。它的执行顺序也是按照中间件注册顺序的倒序执行。
class Mymiddlewera(MiddlewareMixin):
def process_request(self,request):
print('我是app02中mymiddlewera中第一个自定义的中间件方法请求方法')
print('',request)
# return HttpResponse('好想好好的睡个一夜直到天亮') def process_response(self,requset,response):
print('我是app02中mymiddlewera中第一个自定义的中间件方法响应方法')
return response # 必须将response接收到的数据返回,不然报错 def process_view(self,request,view_func,view_args,view_kwargs):
print('111,你说啥就是啥吧')
print(view_func)
print(view_args)
print(view_kwargs) def process_exception(self,request,exception):
print('222,你可真烦人啊!')
print(exception)
process_template_response(用的比较少)
process_template_response(self, request, response)
它的参数,一个HttpRequest对象,response是TemplateResponse对象(由视图函数或者中间件产生)。
process_template_response是在视图函数执行完成后立即执行,但是它有一个前提条件,那就是视图函数返回的对象有一个render()方法(或者表明该对象是一个TemplateResponse对象或等价方法)。
class Mymiddlewera(MiddlewareMixin):
def process_request(self,request):
print('我是app02中mymiddlewera中第一个自定义的中间件方法请求方法')
print('',request)
# return HttpResponse('好想好好的睡个一夜直到天亮') def process_response(self,requset,response):
print('我是app02中mymiddlewera中第一个自定义的中间件方法响应方法')
return response # 必须将response接收到的数据返回,不然报错 def process_view(self,request,view_func,view_args,view_kwargs):
print('111,你说啥就是啥吧')
print(view_func)
print(view_args)
print(view_kwargs) def process_exception(self,request,exception):
print('222,你可真烦人啊!')
print(exception) def process_template_response(self,request,response):
print('我是app02中的mymiddlewera中第一个自定义的render方法')
return response
views.py
def index(request):
print('我是index,哈哈哈哈')
# print(request.method) def render():
print('')
# return 123
return HttpResponse('haodezhidaole ')
obj = HttpResponse('ok')
# print(1111)
obj.render=render # 这一步实际上触发了process return obj
视图函数执行完之后,立即执行了中间件的process_template_response方法,顺序是倒序,先执行MD1的,在执行MD2的,接着执行了视图函数返回的HttpResponse对象的render方法,返回了一个新的HttpResponse对象,接着执行中间件的process_response方法。
总结:
process_request:请求来的时候从下往上依次执行每一个中间件里面的process_request
process_response:响应走的时候会从下往上依次执行执行每一个中间件的process_response方法
process_view:路由匹配成功,执行视图函数之前自动触发(顺序是从上往下依次执行),view_func是执行视图函数的名字
process_exception:当视图函数出现报错,会自动触发,顺序是依次往下往上执行
process_template_response:当你返回对象的时候有一个render()方法的时候会触发,执行顺序从下往上依次执行
***************
django中渐渐暗能够帮我实现 网站全局的身份验证,黑名单,白名单,访问频率限制,反爬相关等等
》》》:django用来帮你做全局相关的功能校验
RBAC:基于角色的权限管理(不同的客户可以给出不同的访问权限)
所以后面只要是涉及到了全局相关,我们就可以直接再中间件这里进行操作,比如说去数据库中进行校验这个用户权限,然后只对他开放特定的功能块儿!
跨站请求伪造(CSRF)
钓鱼网站就是建一个和正常的网站一模一样的网站,然后用户在输入的时候调的也是正常网站的接口去处理,所以用户的钱会扣掉,但是并没有转给指定的人,其实就是建了一个和正常网站一模一样的东西,然后偷偷的在转给目标用户那里,偷偷的将input框当前的name去掉,然后用了一个hidden隐藏起来,在隐藏起来的input框中给一个默认的value,具体示例如下
模拟钓鱼网站示例
正常网站 views.py
def transfer(request):
if request.method == 'POST':
username = request.POST.get('name')
money = request.POST.get('money')
others = request.POST.get('others')
print('%s 给 %s 转了 %s块钱'%(username,others,money))
return render(request,'transfer.html')
正常网站transfer.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
<script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
</head>
<body>
<h1>正经网站</h1>
<form action="" method="post">
<p>name:<input type="text" name="name"></p>
<p>money:<input type="text" name="money"></p>
<p>others:<input type="text" name="others"></p>
<input type="submit">
</form>
</body>
</html>
钓鱼网站 transfer.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
<script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
</head>
<body>
<h1>钓鱼网站</h1>
<form action="http://127.0.0.1:8000/transfer" method="post">
<p>name:<input type="text" name="name"></p>
<p>money:<input type="text" name="money"></p>
<p>others:
<input type="text" >
<input type="hidden" name="others" value="mcc" style="display: none" >
</p>
<input type="submit">
</form>
</body>
</html>
这样就是最开始的网络诈骗ヽ(*。>Д<)o゜ヽ(*。>Д<)o゜
那我们学习了以后,如何保证我们的网站的安全呢?
Django之CBV装饰器,跨站请求伪造,auth认证的更多相关文章
- django CBV装饰器 自定义django中间件 csrf跨站请求伪造 auth认证模块
CBV加装饰器 第一种 @method_decorator(装饰器) 加在get上 第二种 @method_decorator(login_auth,name='get') 加在类上 第三种 @met ...
- Django中间件,CSRF(跨站请求伪造),缓存,信号,BootStrap(模板)-响应式(栅格)+模板
Django中间件,CSRF(跨站请求伪造),缓存,信号,BootStrap(模板)-响应式(栅格)+模板 1.中间件(重要): 在Django的setting中有个MIDDLEWARE列表,里面的东 ...
- Django:CSRF(Cross-request forgery)跨站请求伪造
一.CSRF是什么 二.CSRF攻击原理 三.CSRF攻击防范 一.CSRF是什么 CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Atta ...
- Django day15 (二) csrf的 跨站请求伪造 与 局部禁用 , 局部使用
一: csrf 的跨站请求伪造 二: csrf 的局部禁用 , 局部使用
- django----csrf跨站请求伪造 auth组件 settings源码 importlib模块
目录 importlib模块 csrf跨站请求伪造 form表单发送 ajax发送 csrf装饰器 auth模块 如何创建超级用户(root) 创建用户 校验用户名和密码是否正确 保存用户登录状态 判 ...
- django如何防止csrf(跨站请求伪造)
什么是CSRF 下面这张图片说明了CSRF的攻击原理: Django中如何防范CSRF Django使用专门的中间件(CsrfMiddleware)来进行CSRF防护.具体的原理如下: 1.它修改当前 ...
- django之跨站请求伪造csrf
目录 跨站请求伪造 csrf 钓鱼网站 模拟实现 针对form表单 ajax请求 csrf相关的两个装饰器 跨站请求伪造 csrf 钓鱼网站 就类似于你搭建了一个跟银行一模一样的web页面 , 用户在 ...
- Django之cfrs跨站请求伪造和xfs攻击
跨站请求伪造 一.简介 django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成.而对于django中设置防 ...
- Django之CSRF 跨站请求伪造
一.简介 1.点我了解什么是跨站请求伪造 2.django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成.而对 ...
- csrf 跨站请求伪造相关以及django的中间件
django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware来完成. 1.django中常用的中间件? - proces ...
随机推荐
- Flutter混合开发:Android接入Flutter
Flutter Google推出已经已经一年多了,单个 Flutter 项目的开发流程已经很成熟了.对与个人开发者来说使用 Flutter 开发一个跨平台的App挺有意思.但是对于现有的项目改造来说还 ...
- 使用Handler的步骤
使用Handler的大致流程: 1.首先创建一个Handler对象,可以直接使用Handler无参构造函数创建Handler对象,也可以继承Hander类,重写HandleMessage方法来创建Ha ...
- [css-animation-101] 8 multiple transitions
原文地址:css animation 101 #multiple-transitions 原文作者:Donovan Hutchinson 译者:JobbyM 到目前为止,我们已经讨论了一个过渡如何在一 ...
- HTML中的<%%>是什么意思
背景: 今天在nutzwk框架中看到这段代码. 在index.html界面 <% layout("/layouts/platform.html"){ %> <di ...
- java基础-略知一二
Collection Set HashSet LinkedHashSet SortedSet TreeSet List ArrayList 构造方法 LinkedList 构造方法 Map 特性 方法 ...
- 【快速上手】Git的使用教程
创建Git仓库 git init 查看当前仓库情况 git status 添加修改 git add (file) or git add . 查看未提交的修改 git diff 撤销提交操作 git r ...
- C++扬帆远航——18(项目五2,递归式)
/* * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:qiushi.cpp * 作者:常轩 * 微信公众号:World ...
- 1、【Spark】Spark安装
本文基于的环境 Red Hat Linux Enterprise 7 x86_64 jdk 1.7.0_79 Python 2.7Spart spark-1.5.2-bin-hadoop2.6 官方要 ...
- 聊一聊MyBatis 和 SQL 注入间的恩恩怨怨
整理了一些Java方面的架构.面试资料(微服务.集群.分布式.中间件等),有需要的小伙伴可以关注公众号[程序员内点事],无套路自行领取 更多优选 一口气说出 9种 分布式ID生成方式,面试官有点懵了 ...
- 前端每日实战:10# 视频演示如何用纯 CSS 创作一个同心圆弧旋转 loader 特效
效果预览 按下右侧的"点击预览"按钮在当前页面预览,点击链接全屏预览. https://codepen.io/zhang-ou/pen/OZmXQX 可交互视频教程 此视频是可以交 ...