【问题标题】:Template-less Django + AJAX: Does Django's CSRF token get updated during the course of a browsing session?无模板 Django + AJAX:Django 的 CSRF 令牌是否在浏览会话过程中更新?
【发布时间】:2013-12-20 03:07:18
【问题描述】:

我目前的设置是 AngularJS + Django 1.5,我完全放弃了使用 Django 的模板引擎(即后端几乎是一个 API 服务器)。

由于我没有使用 csrf_token 模板标签,因此 Django 不会设置和发送 csrftoken cookie 作为响应。按照官方文档的指示,应该使用ensure_csrf_cookie() 装饰器来强制装饰视图发送csrftoken cookie。

我已将ensure_csrf_cookie() 装饰器应用于视图,它为我的Web 客户端在引导时调用的第一个GET 请求提供服务。这样,我的 Web 客户端就获得了 CSRF 令牌,此后就可以向服务器调用不安全的方法(例如 POST)。

只有在浏览会话结束之前 CSRF 令牌保持不变时,上述设置才能正常工作。

问题: Django 的 CSRF 令牌会在浏览会话期间更新吗?如果“是”,这是否意味着我需要将 ensure_csrf_cookie() 装饰器应用于我拥有的所有视图?

【问题讨论】:

  • 1) 不太可能,但恕我直言,这是一个实现细节,我建议不要依赖这种行为。 2) 只需编写一个由ensure_csrf_cookie() 修饰的 Mixin 或 View 基类,并将其用作 API 视图的基础(可能还有很多样板代码您也可以移到那里)。
  • 谢谢@PauloScardine。我同意你所说的。如果为所有服务器响应设置了 csrf 令牌 cookie,会不会有任何安全隐患?
  • AFAIK 没有安全隐患,像 Django-REST-Framework 这样的框架可以做到这一点——事实上,你应该在下一个项目中考虑它,因为它为你提供了诸如分页、节流和花哨的权限系统之类的东西。
  • @PauloScardine - 哈哈。我正在为当前项目使用 Django REST Framework。我喜欢它。但我没有看到 rest_framework 在其基本视图(即 APIView)或其任何通用视图中强制 CSRF cookie。我错过了什么吗?请注意,我有 rest_framework v2.3.8。
  • 您是否启用了基于会话的身份验证?

标签: ajax django csrf django-csrf


【解决方案1】:

1) Django 的 CSRF 令牌是否会在浏览会话期间更新?

看起来CSRF 令牌在每个会话中都是唯一的,但它基于我的观察,我没有“官方”来源。使用 Angular.js,我可以毫无问题地使用以下代码:

angular.module('app', ...)
  .config(function($httpProvider) {
    var cookies = document.cookie.split(';');
    var csrftoken = _.find(cookies, function(v) { 
                      return v.trim().indexOf('csrftoken=') == 0; 
                    });
    if(csrftoken) {
      $httpProvider.defaults.headers.common['X-CSRFToken'] = csrftoken.split('=')[1];
    }
  })

由于我从 Django 提供 HTML,所以当 Angular 引导时,cookie 已经存在。

2) 如果“是”,这是否意味着我需要将 ensure_csrf_cookie() 装饰器应用于我拥有的所有视图?

如果CSRF,您可以尝试CORSOtto Yiu 维护 django-cors-headers 包,已知它可以与 REST 框架 API 一起正常工作。

一些(未经测试的)想法可以应用ensure_csrf_cookie()

  • 猴子补丁 APIView
  • 创建一个 CSRFCookie mixin 并将其添加到您的视图中
  • ensure_csrf_cookie() 应用于您的基类

【讨论】:

    【解决方案2】:

    支持@Paulo Scardine 应用ensure_csrf_cookie() 的想法(我认为这是有效且有用的),如果您绝对需要ensure_csrf_cookie(),我想为其添加一个新的可能解决方案你的意见。您可以编写自定义middleware,并实现ensure_csrf_cookie 中的逻辑。像这样的:

    在你的app.middleware.py

    from django.middleware.csrf import get_token
    
    
    class EnsureCsrfCookie(object):
    
        def process_request(self, request):
            # Forces process_response to send the cookie
            get_token(request)
    

    您的settings 文件中的课程将中间件添加到MIDDLEWARE_CLASSES

    MIDDLEWARE_CLASSES = (
        .,
        .,
        .,
        'app.middleware.EnsureCsrfCookie',
        .,
        .,
        .,
    )
    

    面对这个问题只是一个想法。我希望它对将来的某些人有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-10
      • 2010-09-13
      • 2014-10-16
      • 2016-12-06
      相关资源
      最近更新 更多