您的位置:首页 > 编程语言 > Go语言

django中间件,CRSF(跨站请求攻击),Auth认证模块

2019-04-23 20:45 44 查看

django请求响应的生命周期简介

浏览器发送请求,通过web服务网管接口(wsgiref)封装解析成request,经过django的中间件(默认7个中间件,可自定义中间件,从上至下),经过urls.py进行路由的解析,到达对应的视图函数,视图函数和templates、models进行数据的处理和交互显示,视图函数处理完成之后返回request对象,依次通过urls.py,django的中间件(从下至上),web服务网关接口返回给浏览器。

django中间件介绍

官方说法:中间件是一个用来处理django请求和响应的框架级别的钩子,它是一个轻量、低级别的插件系统,用于在全局范围内改变django的输入输出。每个中间件组件都负责一些特定的功能。
说的直白一点就是在执行是视图函数之前和执行之后,可以做一些额外的操作。它的本质上就是一个自定义的类,类中定义几个方法,django会在请求的特定时间去执行这些方法。
从我们安装和运行django框架开始我们就在是有中间件,可能只是没有注意而已。
默认的django中间件

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

django中间件在请求的时候是从上至下执行的,在响应的时候是从下至上的

自定义中间件

新建一个文件夹,在文件夹中新建一个middleware.py文件

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse,render

class MyMiddleWare(MiddlewareMixin):
def process_request(self,request):
print('我是第一个自定义的中间件中process_request方法')
# return HttpResponse('我是第一个中间件里面返回的对象')
# return render(request, 'index.html')

def process_response(self,request,response):
print('我是第一个自定义的中间件中process_response方法')
return response

def process_view(self, request, view_func, view_args, view_kwargs):
print('我是第一个自定义的中间件中process_view方法')
print(view_func.__name__)

def process_exception(self, request, exception):
print("我是第一个自定义的中间件中process_exception方法",exception)

def process_template_response(self, request, response):
print('我是第一个自定义的中间件中process_template_response方法')
return response

class MyMiddleWare1(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('我是第二个自定义的中间件中process_view方法')
print(view_func.__name__)

def process_exception(self, request, exception):
print("我是第二个自定义的中间件中process_exception方法",exception)

def process_template_response(self, request, response):
print('我是第二个自定义的中间件中process_template_response方法')
return response

这样就自定义了两个中间件,然后在django的配置文件中,注册一下这两个中间件

CRSF(跨站请求攻击)

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

开两个django项目,模拟转账的现象

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

如何去写这个特殊的字符串呢?模版语法有一个固定的写法{% csrf_token %},必须写在form表单内

浏览器查看改标签的值,并且每次都在刷新。再来演示刚刚转账的示例

ajax中如何设置csrf_token

# 第一种页面上先写一个{%csrf_token%}标签,后面用jquery查找标签取值组成键值对放入data中即可

csrf_token局部使用

# 只想给某个视图韩式加上csrf校验
from django.views.decorators.csrf import csrf_exempt,csrf_protect

# 局部禁用
@csrf_exempt
def index(request):
pass

# 局部使用
@csrf_protect
def login(request):
pass

# CBV比较特殊,不能单独加在某个方法上
# 只能加在类上或dispatch方法上
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt,csrf_protect
@method_decorator(csrf_exempt,name='get')  # 第一种
class Csrf_Token(View):
@method_decorator(csrf_exempt)  # 第二种
def dispatch(self,request,*args,**kwargs):
res = super().dispatch(request,*args,**kwargs)
return res
@method_decorator(csrf_exempt)  # 这里这么写不行!!!
def get(self,request):
pass
def post(self,request):
pass

Auth认证模块

执行数据库迁移的那两条命令时,即使我们没有建表,django是不是也会创建好多张表?我们创建之后去看一下里面的一个叫auth_user表,既然是表,那肯定应该有对应的操作改表的方法

auth_user表记录的添加

  • 创建超级用户(不可手动插入,因为密码是加密的)
  • 简单使用auth认证
from django.contrib import auth
def login(request):
if request.method == 'POST':
name = request.POST.get('name')
pwd = request.POST.get('pwd')
user = auth.authenticate(request,username=name,password=pwd)
# 类似于user=models.User.objects.filter(username=name,password=pwd).first()
if user:
return redirect('/home/')
return render(request,'login.html')
  • 只是简单的验证信息不行,还需要给当前成功登陆的用户保存登陆状态,之前是通过cookie或者session,现在呢,auth也给你提供了一个比较好用的方法
if user:
# 等价于request.session['name']=name
auth.login(request,user)  # 登陆,其实就把用户信息放到session中,跑一下验证session表
  • 上面的验证和登陆其实不是它的亮点,亮点在于只要登陆成功执行auth.login(request,user)之后在其他任意的视图函数中都通过request.user获取当前登陆用户对象
  • 注销
auth.logout(request)
# 等价于删除session数据request.session.flush()
  • 装饰器校验是否登录及跳转
om django.contrib.auth.decorators import login_required

@login_required(login_url='/login/',redirect_field_name='old')  # 没登陆会跳转到login页面,并且后面会拼接上你上一次想访问的页面路径/login/?next=/test/,可以通过参数修改next键名
def my_view(request):
pass
  • 如果我所有的视图函数都需要装饰并跳转到login页面,那么我需要写好多份
# 可以在配置文件中指定auth校验登陆不合法统一跳转到某个路径
LOGIN_URL = '/login/'  # 既可以局部配置,也可以全局配置
  • 新增auth_user表记录
User.objects.create_superuser(username=username, password=password, email=email)  # 超级用户
User.objects.create_user(username=username, password=password, email=email)  # 普通用户
  • 校验密码,修改密码
request.user.check_password(pwd)
request.user.set_password(pwd)
request.user.save()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐