首页 > 其他分享 >Django CSRF认证的几种解决方案

Django CSRF认证的几种解决方案

时间:2023-02-23 18:57:25浏览次数:43  
标签:请求 解决方案 request Django token csrf CSRF import data

什么是CSRF

浏览器在发送请求的时候,会自动带上当前域名对应的cookie内容,发送给服务端,不管这个请求是来源A网站还是其它网站,只要请求的是A网站的链接,就会带上A网站的cookie。浏览器的同源策略并不能阻止CSRF攻击,因为浏览器不会停止js发送请求到服务端,只是在必要的时候拦截了响应的内容。或者说浏览器收到响应之前它不知道该不该拒绝。

攻击过程

用户登陆A网站后,攻击者自己开发一个B网站,这个网站会通过js请求A网站,比如用户点击了某个按钮,就触发了js的执行。

防止攻击

  • Double Submit Cookie

攻击者是利用cookie随着http请求发送的特性来攻击。但攻击者不知道 cookie里面是什么。

Django中是在表单中加一个隐藏的 csrfmiddlewaretoken,在提交表单的时候,会有 cookie 中的内容做比对,一致则认为正常,不一致则认为是攻击。由于每个用户的 token 不一样,B网站上的js代码无法猜出token内容,对比必然失败,所以可以起到防范作用。

  • Synchronizer Token

和上面的类似,但不使用 cookie,服务端的数据库中保存一个 session_csrftoken,表单提交后,将表单中的 token 和 session 中的对比,如果不一致则是攻击。

这个方法实施起来并不困难,但它更安全一些,因为网站即使有 xss 攻击,也不会有泄露token的问题。

Django使用CsrfViewMiddleware中间件进行CSRF校验,默认开启防止csrf(跨站点请求伪造)攻击,在post请求时,没有携带csrf字段,导致校验失败,报403错误。那么我们如何解决这种403错误呢?

2. 前端表单中增加csrf信息

<form enctype="multipart/form-data" method="post" action="{% url 'add_data' %}">
    {% csrf_token %}
</form>

一定要注意后端使用render而不要使用rendertoresponse进行渲染,这样前端就会有csrf_token变量,前端cookies中也会出现csrftoken数据,然后在HTML中使用即可。这种方式只限制在form表单中使用,ajax请求不支持。

3. 指定请求去掉CSRF校验

可以只针对指定的路由去掉CSRF校验,这也分为两种情况:

  • FBV:以函数实现路由处理

# 导入,可以使此次请求忽略csrf校验
from django.views.decorators.csrf import csrf_exempt

# 在处理函数加此装饰器即可
@csrf_exempt
def add_data(request):
    result = {}
    # TODO

    return HttpResponse(result)

    2.CBV:以类实现路由处理

from django.views import View
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator


class IndexView(View):
    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def get(self, request, *args, **kwargs):
        return render(request, 'home.html')

    def post(self, request, *args, **kwargs):
        data = request.POST.get('data')
        qr_path = gen_qrcode(data)
        return HttpResponse(qr_path)

或者用下面的方式,把装饰器放在类外面

from django.views import View
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator


@method_decorator(csrf_exempt, name='dispatch')
class IndexView(View):
    def get(self, request, *args, **kwargs):
        return render(request, 'home.html')

    def post(self, request, *args, **kwargs):
        data = request.POST.get('data')
        qr_path = gen_qrcode(data)
        return HttpResponse(qr_path)

  4. 为所有请求添加csrf校验数据(推荐)

以上方式都有限制,适用范围比较窄,我们需要一种可以一劳永逸的方式:让所有请求都携带csrf数据。因为我们是使用Django模板渲染前端页面的,所以一般会先定义一个base.html,其他页面通过{% extends "base.html" %}来引入使用,那么在base.html中添加ajax的全局钩子,在请求时添加csrf数据即可。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>{% block title %}首页{% endblock %}</title>
    <link rel="stylesheet" href="{% static 'css/base.css'%}">
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <script>
        $.ajaxSetup({
            data: {
                csrfmiddlewaretoken: '{{ csrf_token }}'
            }
        })
    </script>
    {% block css %}
    {% endblock %}
</head>
<body>

 

标签:请求,解决方案,request,Django,token,csrf,CSRF,import,data
From: https://www.cnblogs.com/mengdie1978/p/17149070.html

相关文章

  • Django 模型 Meta 选项详解
    1.了解Meta内部类每个模型类(Model)下都有一个子类Meta,这个子类就是定义元数据的地方。Meta类封装了一些数据库的信息,称之为Model的元数据。Django会将Meta中的......
  • Django框架课-创建游戏界面 (2)
    Django框架课-创建游戏界面(2)bug修改bug1:获取鼠标在画布中的相对坐标之前写的只是直接获取在屏幕中的坐标,默认画布是在左上角的,如果acapp的窗口不在屏幕左上角,获取到......
  • 安装 conda 后的部分问题解决方案
    WindowsPowerShell无法使用Conda虚拟环境Anaconda和Miniconda均适用。打开环境变量,选中用户变量(或者系统变量也可以)中的Path,点击编辑。将如下conda安......
  • Django路由层
    目录Django路由pathDjango自带url参数转换器url转换器具体使用方法re_path路由匹配冲突re_path无名有名分组无名分组有名分组反向解析反向解析静态路由反向解析动态路由Dj......
  • Django rest_framework
    serializersfromrest_frameworkimportserializersclassSerializerClass(serializers.ModelSerializer):classMeta:model=ModelClass#1.......
  • SpringBoot21 - 数据层解决方案 SQL
    数据层解决方案-SQL​ SSMP整合的时候数据层解决方案涉及到了哪些技术?MySQL数据库与MyBatisPlus框架,后面又学了Druid数据源的配置,所以现在数据层解决方案可以说是Mysql......
  • Django 初步运行过程分析笔记
    2.django运行过程分析第一个过程分析:django启动过程pythonmangage.pyrunserver0.0.0.0:8000这个命令先被python的sys.argv接收起来,保存成[mangage.py,runserver,0.0......
  • node.js实现国标GB28181设备接入sip服务器解决方案SkeyeVSS国标视频云平台
    GB28181接入服务器是SkeyeVSS接入GB28181设备/平台的信令交互服务器,GB28181将SIP定位为联网系统的主要信令基础协议,并利用SIP协议的有关扩展,实现了对非会话业务的兼顾,例如......
  • django分页器
    定义类#基于bootsrapclassPagination(object):def__init__(self,current_page,all_count,per_page_num=2,pager_count=11):"""封装分页相......
  • 瓴羊 Quick BI 提供移动端自助分析整体解决方案,Fine BI、Smart BI 何时赶上?
    进入2023,全国上下都在为了提振经济促进消费积极努力。经济活力复苏的同时,各大企业、品牌商家等也在努力通过数据驱动持续构建品牌的长期可持续发展动能。为了帮助企业客户......