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 == '':
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('') #设置新密码
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/' #全局配置
def login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'jason' and password =='':
#相当于比对完之后 之前都是重定向 或者Httoresonse ok
path = request.GET.get('next') print(path) if path:
obj = redirect(path)
else:
obj = redirect('/home/')
obj.set_cookie('name','jason',expires=5)
return obj
return render(request,'login.html') from functools import wraps
def login_auth(func):
@wraps(func)
def inner(request,*args,**kwargs): path = request.get_full_path() if request.COOKIES.get('name'):
return func(request,*args,**kwargs)
return redirect('/login/?next=%s'%path)
return inner @login_auth
def home(request):
return HttpResponse('我是home页面,只有登录了才能看到')
参考理解代码
自定义模型表引用auth功能
如何扩张auth_user表?
一对一关联(不推荐)
from django.contrib.auth.model import User class 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表的操作方法,现在全部用自定义的表均可实现
django CBV装饰器 自定义django中间件 csrf跨站请求伪造 auth认证模块的更多相关文章
- django之cookies,session 、中间件及跨站请求伪造
cookies 和session 为什么会有cookie? 由于http协议是无状态的,即用户访问过后,不留痕迹(状态可以理解为客户端和服务器在某次会话中产生的数据,那无状态的就以为这些数据不会被 ...
- Web框架之Django_09 重要组件(Django中间件、csrf跨站请求伪造)
摘要 Django中间件 csrf跨站请求伪造 一.Django中间件: 什么是中间件? 官方的说法:中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个轻量.低级别的插件系统,用于 ...
- Web框架之Django重要组件(Django中间件、csrf跨站请求伪造)
Web框架之Django_09 重要组件(Django中间件.csrf跨站请求伪造) 摘要 Django中间件 csrf跨站请求伪造 一.Django中间件: 什么是中间件? 官方的说法:中间件是 ...
- python 全栈开发,Day87(ajax登录示例,CSRF跨站请求伪造,Django的中间件,自定义分页)
一.ajax登录示例 新建项目login_ajax 修改urls.py,增加路径 from app01 import views urlpatterns = [ path('admin/', admi ...
- Django框架(十六)-- 中间件、CSRF跨站请求伪造
一.什么是中间件 中间件是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出 二.中间件的作用 如果你想修改请求,例如被传送到view ...
- Django框架(十二)-- 中间件、CSRF跨站请求伪造
中间件 一.什么是中间件 请求的时候需要先经过中间件才能到达django后端(urls,views,templates,models) 响应的时候也需要经过中间件才能到达web服务网关接口 djang ...
- Django框架(十七)—— 中间件、CSRF跨站请求伪造
目录 中间件 一.什么是中间件 二.中间件的作用 三.中间件执行顺序 四.自定义中间件 1.导包 2.定义类,继承MiddlewareMixin 3.在视图函数中定义一个函数 4.在settings的 ...
- [Django高级之中间件、csrf跨站请求伪造]
[Django高级之中间件.csrf跨站请求伪造] Django中间件 什么是中间件? Middleware is a framework of hooks into Django's request ...
- django 中间键 csrf 跨站请求伪造
django中间件和auth模块 Django中间件 由django的生命周期图我们可以看出,django的中间件就类似于django的保安,请求一个相应时要先通过中间件才能到达django后端( ...
随机推荐
- Flask-websocket实现聊天功能
群聊无昵称 原生js代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&q ...
- JavaWeb_(Spring框架)Spring整合Hibernate
Dao层类要继承HibernateDaoSupport.java父类 原先使用Hibernate框架hibernate.cfg.xml配置数据库 <hibernate-configuration ...
- LG2216 理想的正方形
题意 有一个\(a \times b\)的整数组成的矩阵,现请你从中找出一个\(n \times n\)的正方形区域,使得该区域所有数中的最大值和最小值的差最小 思路 对于每一列,都用两个单调队列维护 ...
- redis 数据类型详解 以及 redis适用场景场合(滴滴)
滴滴的面试官问了个问题关于redis的: 我现在想服务器每分钟接收一个用户的请求小于60个,如何处理: 答:使用Redis 缓存服务器,可以设置key=用户ID value不停地加一到了60就停止,然 ...
- Eratos筛法(筛选素数)
对于n以内的非素数必有k*n1=n(n1<n) 所以 可有p1,2p2,3p3把非素数筛选掉 实现代码: #include<iostream> #include<string ...
- 清空Linux缓存
清空Linux的缓存 sync > /proc/sys/vm/drop_caches > /proc/sys/vm/drop_caches > /proc/sys/vm/drop_c ...
- JDK与CGlib动态代理的实现
应用的原型为 执行者:房屋中介Agency(分为JDKAgency.CGlibAgency) 被代理对象:程序员Programmer 被代理对象的实现接口:租户Tenement(CGlibAgency ...
- 解决Sublime Text3中文显示乱码问题
一.安装包管理器 使用Ctrl+~快捷键或者通过View->Show Console菜单打开命令行,粘贴如下代码 import urllib.request,os; pf = 'Package ...
- 性能测试 | 服务器CPU使用率高分析实例
前面我们讨论系统调用的时候结论是耗时200ns-15us不等.不过我今天说的我的这个遭遇可能会让你进一步认识系统调用的真正开销.在本节里你会看到一个耗时2.5ms的connect系统调用,注意是毫秒, ...
- parted对大容量磁盘进行分区
Linux系统中MBR与GPT的区别 主引导记录(Master Boot Record , MBR)是指一个存储设备的开头 512 字节.它包含操作系统的引导器和存储设备的分区表. 全局唯一标识分区表 ...