zoukankan      html  css  js  c++  java
  • Django 设置 cookie 中的 csrftoken

    遇到一个问题是,CMDB项目的前端删除数据要向后端发送 DELETE 请求,需要验证 CSRF 。但是之前项目一直都是 GET 请求获取的数据,浏览器的 cookies 中没有 csrftoken 的值,而发送请求之前是从 cookies 中获取 csrftoken 的值,没有值也就没法通过验证。所以就要人为的设置一下 cookies 中的 csrftoken 值。

      出现这个问题的前提是:

      1、习惯ajax方式提交POST等请求;

      2、习惯从cookie中找csrftoken;

      一般我们认为cookie里的csrftoken是由csrftoken middleware所设置的,事实确实如此,但也不完全是。贴一段CsrfViewMiddleware的代码:

    def process_response(self, request, response):
            if not getattr(request, 'csrf_cookie_needs_reset', False):
                if getattr(response, 'csrf_cookie_set', False):
                    return response
    
            if not request.META.get("CSRF_COOKIE_USED", False):
                return response
    
            # Set the CSRF cookie even if it's already set, so we renew
            # the expiry timer.
            self._set_token(request, response)
            response.csrf_cookie_set = True
            return response
    def _set_token(self, request, response):
            if settings.CSRF_USE_SESSIONS:
                request.session[CSRF_SESSION_KEY] = request.META['CSRF_COOKIE']
            else:
                response.set_cookie(
                    settings.CSRF_COOKIE_NAME,
                    request.META['CSRF_COOKIE'],
                    max_age=settings.CSRF_COOKIE_AGE,
                    domain=settings.CSRF_COOKIE_DOMAIN,
                    path=settings.CSRF_COOKIE_PATH,
                    secure=settings.CSRF_COOKIE_SECURE,
                    httponly=settings.CSRF_COOKIE_HTTPONLY,
                )
                # Set the Vary header since content varies with the CSRF cookie.
                patch_vary_headers(response, ('Cookie',))

    这段代码的重点在于对CSRF_COOKIE_USED的检查,如果没有设置,middleware会直接返回response而不在cookie里设置csrftoken。

    看别人说有三种方法设置CSRF_COOKIE_USED。

    1. 手动设置,在view 中添加 

    request.META["CSRF_COOKIE_USED"] = True

    2. 手动调用 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')

    3. 在HTML模板中添加 {% csrf_token %}

    4. 在需要设置cookie的视图上加装饰器 ensure_csrf_cookie()

    from django.views.decorators.csrf import ensure_csrf_cookie
    
    @ensure_csrf_cookie
    def server(request):
    
        return render(request, 'server.html')

    亲测方法2、3、4有效,都能在cookie中设置csrftoken,但是方法1会报错,需要自己生成64位的csrftoken。

    request.META['CSRF_COOKIE']= 'abc' 配合此行代码,cookie中的csrftoken设置成了‘abc’.

    所以,如果不想在模板中添加{% csrf_token %}标签,推荐使用方法2中的get_token(request)方法和方法4

    CSRF保护机制的工作原理:https://docs.djangoproject.com/en/1.11/ref/csrf/#how-it-works

    参考:http://www.jianshu.com/p/9346bbc3a8f1

  • 相关阅读:
    【BZOJ 3282】Tree Link Cut Tree模板题
    【BZOJ 2002】【Hnoi 2010】弹飞绵羊 分块||Link Cut Tree 两种方法
    【BZOJ 1507】【NOI 2003】&【Tyvj P2388】Editor 块状链表模板题
    小结-Splay
    【BZOJ 3545】【ONTAK 2010】Peaks & 【BZOJ 3551】【ONTAK 2010】Peaks加强版 Kruskal重构树
    【BZOJ 3732】 Network Kruskal重构树+倍增LCA
    【BZOJ 3674】可持久化并查集加强版&【BZOJ 3673】可持久化并查集 by zky 用可持久化线段树破之
    【BZOJ 1901】【Zju 2112】 Dynamic Rankings 动态K值 树状数组套主席树模板题
    1020: [SHOI2008]安全的航线flight
    POJ
  • 原文地址:https://www.cnblogs.com/Vee-Wang/p/7738539.html
Copyright © 2011-2022 走看看