django CBV装饰器 自定义django中间件 csrf跨站请求伪造 auth认证模块

CBV加装饰器

  第一种  @method_decorator(装饰器)  加在get上

  第二种  @method_decorator(login_auth,name='get')  加在类上

  第三种  @method_decorator(login_auth)  加在dispatch上  3.7的要return super().dispatch

def login(request):if request.method == 'POST':username = request.POST.get('username')pwd = request.POST.get('pwd')if username == 'jason' and pwd == '123':request.session['name'] = 'jason'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

 导入装饰器     翻译 decorators  装饰

from django.utils.decorators import method_decorator

 

 被装饰的类

@method_decorator(login_auth,name='get')    #第二种  name参数必须指定
class MyHome(View):@method_decorator(login_auth)    #第三种  get和post都会被装饰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默认有7个中间件,但是django暴露给用户可以自定义中间件并且里面可以写五种方法 

 

中间件的使用(5个固定的方法)

  process_request:请求来的时候从上往下依次执行每一个中间件里面的process_request方法(如果没有直接通过)

process_request(self,request)

 

  

  process_response:响应走的时候会从下往上依次执行每一个中间件里面的process_response方法(如果没有直接通过)

process_response(self,request,response)return response

 

  

  

  process_view:路由匹配成功执行视图之前自动触发(从上往下依次执行)

process_view(self, request, view_func, view_args, view_kwargs)

 

  

  process_exception:当视图函数报错了,自动触发(从下往上依次执行)

process_exception(self,request,exception)

 

  process_template_response:视图函数返回的对象有一个render()方法(或者表名对象是一个TemplateResponse对象或等价方法)(从上往下依次执行)

process_template_response(self,request,response)

return response

  

 

完整的流程图

 

 

 自定义中间件

  新建一个任意名字的文件夹,里面新建一个任意名字py文件

from django.utils.deprecation import MiddlewareMixin

 

 

 

 

class MyMiddleware(MiddlewareMixi):def process_request(self,request):print(''我是第一个自定义中间件里面的process_request方法')#return HttpResponse('heieheihei')def process_response(self,request,response):print('我是第一个自定义中间件里面的process_response方法')return response    #必须将response形参接收的数据返回,不然直接报错def process_view(self,request,view_func,view_args,view_kwargs):print('我是第一个自定义中间件里面的process_view方法')print(view_func.__name__,view_func)def process_exception(self,request,exception):print('我是第一个自定义中间件里面的process_exception方法')print(exception)def process_template_response(self,request,response):print('我是第一个自定义中间件里面的process_template_response方法')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',# 'app01.mymiddleware.mdzz.MyMiddleware',  #自定义中间件1   应用.文件夹.自定义py文件.自定义中间件类名# 'app01.mymiddleware.mdzz.MyMiddleware1'    #自定义中间件2
]

 

 

 

csrf(跨站请求伪造)

由来:钓鱼网站 拿到银行转账的路径,做一个跟银行一模一样的页面,向银行转账接口提交数据,当用户在钓鱼网站输入对方账户名和转账金额之后,点击发送,其实内部是将对方账户换成了钓鱼网站的造假人员的账户。造成你转账转错账户的情况

<!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/css/bootstrap.min.css"><script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<h1>正经的网站</h1>
<form action="/index3/" method="post">
{#    {% csrf_token %}#}<p>username:<input type="text" name="username"></p><p>money:<input type="text" name="money"></p><p>others:<input type="text" name="others"></p><input type="submit">
</form>
</body>
</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/css/bootstrap.min.css"><script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<h1>钓鱼网站</h1>
<form action="http://127.0.0.1:8000/transfer/" method="post"><p>username:<input type="text" name="username"></p><p>money:<input type="text" name="money"></p><p>others:<input type="text"></p><input type="text" name="others" value="jason" style="display:none"><input type="submit">
</form>
</body>
</html>
钓鱼页面

 

 

如何区分钓鱼网站和正经网站?在正经网站返回页面的时候,在form表单中偷偷塞一个特殊的字符串,后端记下该页面对应的字符串的值,等用户发post请求来的时候,我先去校验特殊的字符串是否匹配

如何去写这个特殊的字符串?

  模板语法有一个固定的写法   必须写在form表单内

{% csrf_token %}   

 

表单中偷偷塞的特殊的字符串

{% csrf_token %}
<input type='hidden' name='csrfmiddlewaretoke' value='"2vzoo1lmSWgLTdI2rBQ4PTptJQKRQTRwnqeWRGcpdAQGagRp8yKg8RX2PdkF4aqh">Ps:value是动态生成的,每一次刷新都不一样

 

 

ajax中如何设置csrf_token  把k和v放在data里面

<form action="/index3/" method="post">
{#    {% csrf_token %}#}<p>username:<input type="text" name="username"></p><p>money:<input type="text" name="money"></p><p>others:<input type="text" name="others"></p><input type="submit">
</form>
<button>ajax</button>
<script>$('button').click(function () {$.ajax({url:'',type:'post',data:{'name':'jason','csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val()},success:function (data) {console.log(data)}})})
</script>

   第二种ajax提交  data:{'csrfmiddlewaretoken':'{{ csrf_token}}'}

 

csrf_token导入

form django.views.decorators.csrf import  csrf_exempt,csrf_protect

 

 

csrf 装饰FBV

不校验csrf

@csrf_exempt
def index1(request):return HttpResponse('ok')

 

校验csrf

@csrf_protect
def index2(request):return HttpResonse('ok')

 

 

csrf装饰给CBV 

先导入装饰器语法

from django.utils.decorators import method_decorator

 

校验csrf

@method_decorator(csrf_protect,name='post')  #第三种
class Index3(View):@method_decorator(csrf_protect)    #第二种def dispatch(self,request,*args,**kwargs):super().dispatch(request,*args,**kwargs)def get(self,request):return HttpResponse('get')@method_decortaor(csrf_protect)    #第一种def post(self,request):return HttpResponse('post')

 

不校验csrf  (只有两种 每种都是全都不校验)

@method_decorator(csrf_exempt,name='dispatch')    #第二种
class Index3(View):@method_decorator(csrf_exempt)    #第一种def dispatch(slef,request,*args,**kwargs):super().dispatch(request,*args,**kwargs)def get(self,request):return HttpResponse('get')def post(self,request):return HttpResponse('post')

 

 

csrf装饰CBV需要注意

  csrf_protect  跟正常的CBV装饰器一样 三种

  csrf_exempt  只能有下面两种方式

          @method_decorator(csrf_exempt,name='dispatch')  #一种

          class Index3(View):

            #@method_decorator(csrf_exempt)  #二种

            def dispatch(self,request,*args,**kwargs):

              super().dispatch(request,*args,**kwargs)

          其实都是给dispatch加

 

Auth认证模块

执行数据库迁移的那两命令式,即使我们没有建表,django也会创建好多张表 auth_user表存放的用户相关的数据

 

auth_user表记录的添加

  创建超级用户(不可手动插入,因为密码是加密的)

    可以使用命令行createsuperuser  会让你输入用户名和密码 但是都是明文输入

  简单使用auth认证  auth.authenticate(校验条件)

from django.contrib import auth
def login(request):if request.method == 'POST':name = request.POST.get('name')pwd = request.POST.get('pwd')#models.User.objects.filter(username=username,password=pwd)user_obj = auth.authenticate(request,username=username,password=pwd)#authenticate 验证if user_obj:#设置用户状态#request.session['name'] = 'jason'auth.login(request,user_obj)  #一旦记录了 ,可以在任意的地方通过request.user获取到当前登录对象return HttpResponse('ok')return render(request,'auth_login.html')

 

只要登录成功执行了auth.login(request,user_obj)

  之后在其他任意的视图函数中都通过request.user获取当前登录用户对象

如果没有执行auth.login    

  request.user打印出来的是匿名用户

如何判断request.user用户是否通过auth.login登录呢?  

  request.user.is_authenticated()

 为何auth.login之后,其他视图函数中就可以通过request.user拿到当前登录对象呢?

  其实就是把用户信息放到django_session表

 

注销  auth.logout(request)

def auth_logout(request):auth.logout(request)    #等价于request.session.flush()return HttpResponse('ok')

 

 

需要找到这张表

from django.contrib.auth.models import User

 

 注册  User.objects.create_user 普通用户 User.objectes.create_superuser  超级用户

def auth_register(request):if request.method = 'POST':username = request.POST.get('username')password = request.POST.get('password')user_obj = auth.authenticate(request,username=username)#校验用户if user_obj:return HttpResponse('当前用户已存在')#User.objectes.create(username=username,password=password)    不能再用create创建#User.objects.create_user(username=username,password=password)    #创建普通用户User.objects.create_superuser(username=username,password=password,email='123@163.com')    #创建超级用户return render(request,'auth_register.html')

 

 

 更改密码   request.user.check_password('密码') 校验密码   request.user.set_password('新密码') 设置新的密码  request.user.save()  保存

def auth_password(request):print(request.user.password)    #密文is_res = request.user.check_password('jason123')    #校验密码是否一致if is_res:request.user.set_password('666')    #设置新密码request.user.save()    #修改密码必须save保存 不然无效return HttpResponse('ok')

 

 

 装饰器校验是否登录及跳转

 auth装饰器

from django.contrib.auth.decorators import login_required

 

 被装饰函数

@login_required(login_url='/login/',redirect_field_name = 'old')    
#没登录会跳转login页面,并且后面会拼接上你上一次想访问的页面路径/login/?next=/你想访问的路径/    可以通过参数修改next键名
def auth_home(request):return HttpResponse('home必须登录才能访问')

 

  如果我所有视图函数都需要装饰并跳转到login页面,那么我要写好多份 为了一劳永逸

#可以在项目配置文件中指定auth校验登录不合法统一跳转到某一个路径
LOGIN_URL = '/login/'    #全局配置

 

 

自定义模型表引用auth功能

如何扩张auth_user表?

  一对一关联(不推荐)

from django.contrib.auth.model import Userclass UserDetail(models.Model):phone = models.CharField(max_length=11)user = models.OnoToOneField(to=User)  #User表在之前创建了 所以可以直接写to=User

 

 

  面向对象的继承

    导入语法

from django.contrilb.auth.models import User,AbstractUser

 

 

class UserInfo(AbstractUser):phone = models.CharField(max_length=32)avatar = models.CharField(max_length=32)

 

 

告诉django不在使用默认的auth_user,而使用我们自己定义的表

  语法:AUTH_USER_MODEL= ‘app名.models里面对相应的模型表名’

在项目settings.py文件中配置

AUTH_USER_MODEL= 'app01.UserInfo'

 

 

自定义认证系统默认使用的数据表之后,我们我们就可以像使用默认的auth_user表那样使用我们的UserInfo表了

库里面也没有auth_user表了,原来auth表的操作方法,现在全部用自定义的表均可实现

 

转载于:https://www.cnblogs.com/lakei/p/11048141.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/569306.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Dubbo理论知识

本文是作者根据官方文档以及自己平时的使用情况&#xff0c;对 Dubbo 所做的一个总结。如果不懂 Dubbo 的使用的话&#xff0c;可以参考我的这篇文章《超详细&#xff0c;新手都能看懂 &#xff01;使用SpringBootDubbo 搭建一个简单的分布式服务》 Dubbo 官网&#xff1a;http…

外观模式(facade)

外观模式是为了解决类与类之间的依赖关系的&#xff0c;像spring一样&#xff0c;可以将类和类之间的关系配置到配置文件中&#xff0c;而外观模式就是将他们的关系放在一个Facade类中&#xff0c;降低了类类之间的耦合度&#xff0c;该模式中没有涉及到接口&#xff0c;看下类…

套接字TCP控制台程序客户端代码示范

套接字TCP控制台程序客户端代码示范 转载于:https://www.cnblogs.com/txwtech/p/11056770.html

widows下nignx的使用

nignx在Linux环境下可以大展身手&#xff0c;在widows环境下也可以启动一定的效果&#xff0c;但是没有linux用的好。 Nginx (engine x) 是一款轻量级的Web 服务器 、反向代理服务器及电子邮件&#xff08;IMAP/POP3&#xff09;代理服务器。 什么是反向代理&#xff1f; 反向代…

享元模式(Flyweight)

享元模式的主要目的是实现对象的共享&#xff0c;即共享池&#xff0c;当系统中对象多的时候可以减少内存的开销&#xff0c;通常与工厂模式一起使用。 FlyWeightFactory负责创建和管理享元单元&#xff0c;当一个客户端请求时&#xff0c;工厂需要检查当前对象池中是否有符合条…

redo

在innodb存储引擎中&#xff0c;事务日志通过重做(redo)日志文件和InnoDB存储引擎的日志缓冲(InnoDB Log Buffer)来实现。当开始一个事务时&#xff0c;会记录该事务的一个LSN(Log Sequence Number&#xff0c;日志序列号)&#xff1b;当事务执行时&#xff0c;会往InnoDB存储引…

迭代子模式(Iterator)

顾名思义&#xff0c;迭代器模式就是顺序访问聚集中的对象&#xff0c;一般来说&#xff0c;集合中非常常见&#xff0c;如果对集合类比较熟悉的话&#xff0c;理解本模式会十分轻松。这句话包含两层意思&#xff1a;一是需要遍历的对象&#xff0c;即聚集对象&#xff0c;二是…

ES6基础之——对象表达式

这里定义了两个变量&#xff0c;一个是dessert&#xff0c;一个是drink,let dessertcake,drinkorange;一、根据两个变量的值去定义一个对象&#xff0c;这个对象叫food,对象里面属性跟变量的名字是一样的,属性值对应上面的变量let dessertcake,drinkorange; let food{ dessert:…

前台获取元素节点

$("#id").childNodes;//获取id的全部子节点&#xff1b; $("#id").parentNode;//获取id的父节点&#xff1b; $("#id").nextSibling;//获取id的下一个兄弟节点 $("#id").previousSibling;//获取id的上一个兄弟节点 $("#id")…

oracle查看执行计划入门

基于Oracle的应用系统很多的性能问题都是由应用系统的SQL性能低劣引起的&#xff0c;因此SQL的性能优化非常重要。要分析与优化SQL的性能&#xff0c;一般是通过查看该SQL的执行计划&#xff0c;然后通过执行计划有针对性地对SQL进行相应的优化。 什么是执行计划&#xff08;Ex…

这半年……

有半日也还清闲的时间&#xff0c;一年的一半也快过完了&#xff0c;那就来谈一谈这半年吧&#xff0c;也对下半年提出点期待。 年初&#xff0c;提出了本年度的的关键词&#xff1a;真实、踏实、勤快。 基于这个指导思想&#xff0c;我对自己半年的评价是&#xff1a;做得不错…

部署自己的tomcat,让tomcat和IIS共同享用服务器的80端口

这几天做了一个网站的CMS系统,当然就要用到TOMCAT来对项目进行部署了.但是客户的服务器上已经安转了我们用.NET制作的OA系统&#xff0c;所以在客户的服务器上已经有完整的IIS7服务&#xff0c;而IIS7默认会占用所有的80端口&#xff08;虽然服务器有两个IP&#xff0c;而它只用…

ueditor1.4.3配置过程(包含单独上传文件以及图片的使用)

这里使用的是ueditor1.4.3的jsp版本的UTF-8版本. 首先下载相应的ueditor,将ueditor文件夹直接拷贝到项目中,文件结构如下所示: 然后将项目要用的jar包导入到lib目录下,在导入之前要先修改一下ueditor的jar包中的bug,这个可以参考这里点击打开链接 接着就是配置jsp目录下的con…

layui如何隐藏弹出层关闭的按钮

layui默认弹出层是带有关闭按钮的&#xff0c;但是在某些场景我们不需要layui的关闭按钮&#xff0c;这时只需添加closeBtn :0即可效果图如下: 示例代码如下: layui.use(layer, function () {var layer layui.layer;layer.open({skin: demo-class,type: 1,title: 登录,area: […

使用httpclient4.3.2来实现微信临时素材的上传

一直在用java来做微信的二次开发&#xff0c;经过一段时间的沉淀总算有了一点门路。其实用java这种强大的语言来做微信的二次开发是很简单的事情。只要解决了加密、https请求的发送、xml的解析这些基本的操作后&#xff0c;用java来进行微信二次开发就变的容易了很多。这里我主…

charles请求入参中有乱码

工作中&#xff0c;需要入参&#xff0c;但是发现入参中&#xff0c;有中文的都是乱码&#xff0c;仔细查阅headers&#xff0c;发现Content-Type是application/x-www-form-urlencoded类型&#xff0c;而实际上&#xff0c;入参是json类型&#xff0c;因此需要强制修改请求头为…

xstream,节点属性起别名时这样的问题你遇到过吗

首先这是我自己定义的一个xstream&#xff0c;这个xstream是为了在处理xml时能够加上<![CDATA[------]]>而特别重写的。这个xstream是没有任何问题的。 private static XStream xstream new XStream(new XppDriver() {public HierarchicalStreamWriter createWriter(Wri…

20190624 Oracle 表分析

dbms_stats.gather_table_stats&#xff08;。。。&#xff09; 参数要注意 正常情况只是为了分析表&#xff0c;也可以通过方法创建记录表 分析的结果会记录的记录表中&#xff0c;当然每次运行会有覆盖&#xff0c;主要分析后的结果。 分析表&#xff0c;记录了目前此表的情况…

用spring搭建微信公众号开发者模式下服务器处理用户消息的加密传输构架(java)

要搭建加密传输的微信公众号消息传输&#xff0c;首先要在开发这平台下载一下微信加密的相关jar包&#xff0c;并做一些准备。准备的步骤如下&#xff1a; 1.打开开发者文档&#xff0c;找到消息加减密--->接入指引&#xff0c;如下图所示&#xff1a; 2.在页面底部找到实例…

Redis 常用命令

1 运行cmd 到redis安装目录&#xff0c;cmd输入redis-cli.exe -h 127.0.0.1 -p 6379 2 密码登录 auth 输入密码 3 设置和获取 set "hello" get "hello" 4 清空 flushall转载于:https://www.cnblogs.com/hanjun0612/p/11078915.html