" name="sm-site-verification"/>
侧边栏壁纸
博主头像
PySuper博主等级

千里之行,始于足下

  • 累计撰写 203 篇文章
  • 累计创建 14 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录
Web

Django中的 CORS、CSRF应用 和 装饰器

PySuper
2020-10-22 / 0 评论 / 0 点赞 / 8 阅读 / 6699 字
温馨提示:
所有牛逼的人都有一段苦逼的岁月。 但是你只要像SB一样去坚持,终将牛逼!!! ✊✊✊

CORS

Django处理CORS的方法

1、安装:

pip install django-cors-headers

2、在settings注册应用

INSTALLED_APPS = (
    ...
    "corsheaders",
    ...
)

3、中间层设置

MIDDLEWARE = [
    ...
    'corsheaders.middleware.CorsMiddleware',
    ...
]

4、添加白名单

# 添加 django-cors-headers 的白名单, 使白名单中的 host 可以进行跨域请求

CORS_ORIGIN_WHITELIST = (
    # 白名单:
    '127.0.0.1:8080',
    'localhost:8080',

    '127.0.0.1:8081',
    'localhost:8081',

    'localhost:8000',
    '127.0.0.1:8000'

    # 添加白名单
    'www.baidu.com:8080'
)

5、允许白名单中的host可以跨域携带cookie

CORS_ALLOW_CREDENTIALS = True

CSRF

跨站请求伪造(CSRF)与跨站请求脚本正好相反。

跨站请求脚本

客户端信任服务器端发送的数据

跨站请求伪造

服务器信任来自客户端的数据

跨站请求伪造是指攻击者通过HTTP请求江数据传送到服务器,从而盗取回话的cookie。

盗取回话cookie之后,攻击者不仅可以获取用户的信息,还可以修改该cookie关联的账户信息。

Form提交

  • csrf验证其实是对http请求中一段随机字符串的验证
  • 如果没有这样一段随机字符串做验证,我们只要在另一个站点,写一个表单,提交到这个地址下,是一样可以发送数据的,这样就造成了极大的安全隐患。
  • 而我们新添加的csrf_token就是在我们自己的站点中,设置的隐藏参数,用来进行csrf验证

Ajax提交

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/login/" method="POST">
        {% csrf_token %}
        <input type="text" name="user" />
        <input type="text" name="pwd" />
        <input type="checkbox" name="rmb" value="1" /> 10s免登录
        <input type="submit" value="提交" />
        <input id="btn" type="button" value="按钮">
    </form>
 
    <script src="/static/jquery-1.12.4.js"></script>
    <script src="/static/jquery.cookie.js"></script>
    <script>
        var csrftoken = $.cookie('csrftoken');
        
        function csrfSafeMethod(method) {
            // these HTTP methods do not require CSRF protection
            return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
        }
        $.ajaxSetup({
            beforeSend: function(xhr, settings) {
                if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                    xhr.setRequestHeader("X-CSRFToken", csrftoken);
                }
            }
        });
 
        $(function () {
            $('#btn').click(function () {
                $.ajax({
                    url:'/login/',
                    type:"POST",
                    data:{'username':'root','pwd':'123123'},
                    success:function (arg) {
                        
                    }
                })
            })
        });
    </script>
</body>
</html>

CSRF装饰器

并不一定所有的接口验证都需要进行csrf验证,我们采用的是在settings.py中间件配置进行全局配置

如果遇到不需要验证的,我们可以采用局部禁用。

FBV

from django.views.decorators.csrf import csrf_exempt,csrf_protect
 
@csrf_protect		#局部使用
def index(request):
    ...

@csrf_exempt		#局部禁用
def login(request):
    ...

CBV

from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django.utils.decorators import method_decorator
from django.shortcuts import render, HttpResponse
from django.views import View

class Cs(View):

   #@method_decorator(csrf_exempt)
    @method_decorator(csrf_protect)
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def get(self, request, *args, **kwargs):
        return HttpResponse('GET,响应内容')

    def post(self, request, *args, **kwargs):
        return HttpResponse('Post,响应内容')

method_decorator

CSRF的装饰器必须加载dispatch上

from django.utils.decorators import method_decorator
# 1.方法
@csrf_protect
def get(request):
	pass
	
# 2.类上
@method_decorator(wraper,name="dispatch")
class Foo(View):

    # @method_decorator(csrf_exempt)
    # @method_decorator(csrf_protect)
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

	def get(self,request):
		pass

	def post(self,request):
		pass

写入Cookie

  • 手动设置,在view 中添加(建议采用2,3,4种方法)
request.META["CSRF_COOKIE_USED"] = True
  • 手动调用 csrf 中的 get_token(request) 或 rotate_token(request) 方法。
from django.middleware.csrf import get_token ,rotate_token

def server(request):
    # get_token(request)       // 两者选一
    # rotate_token(request)   // 此方法每次设置新的cookies
 
    return render(request, 'server.html')
  • 在HTML模板中添加 {% csrf_token %}
  • 在需要设置cookie的视图上加装饰器 ensure_csrf_cookie()
from django.views.decorators.csrf import ensure_csrf_cookie
 
@ensure_csrf_cookie
def server(request):
    return render(request, 'server.html')
0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区