【问题标题】:Does SessionAuthentication work in Tastypie for HTTP POST?SessionAuthentication 在 Tastypie 中是否适用于 HTTP POST?
【发布时间】:2013-03-13 14:53:48
【问题描述】:

除了content-typeapplication/json 之外,我可以在不设置任何标题的情况下使用 SessionAuthentication 和 Tastypie 进行 GET。然而,即使 Header 中的 Cookie 具有会话 ID,HTTP POST 也会失败。它以 401 AuthorizationHeader 失败,但与授权无关。将 SessionAuthentication 更改为 BasicAuthentication 并传递用户名/密码也可以。

有没有人通过 SessionAuthentication 与 Tastypie 一起使用 POST?

【问题讨论】:

    标签: python django rest tastypie


    【解决方案1】:

    是的,我已经让它工作了。您需要做的就是传递 csfr 令牌:

    会话认证

    此身份验证方案使用内置的 用于检查用户是否已登录的 Django 会话。这通常很有用 当 Javascript 在托管 API 的同一站点上使用时。

    它要求用户已经登录并且有一个活跃的会话。 他们 还必须有一个有效的 CSRF 令牌

    这就是你在 jQuery 中的做法:

    // sending a csrftoken with every ajax request
    function csrfSafeMethod(method) {
        // these HTTP methods do not require CSRF protection
        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    }
    $.ajaxSetup({
        crossDomain: false, // obviates need for sameOrigin test
        beforeSend: function(xhr, settings) {
            if (!csrfSafeMethod(settings.type)) {
                xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken'));
            }
        }
    });
    
    $.ajax({
        type: "POST",
        // ...
    

    注意上面写着$.cookie('csrftoken') 的部分。它从 Django 设置的 cookie 中获取 csrf 令牌。

    更新:

    我遇到了一些问题,Django 没有在 Firefox 和 Opera 上设置 cookie。将模板标签{% csrf_token %} 放入您的模板可以解决这个问题。正确的解决方案可能是使用装饰器ensure_csrf_cookie()

    【讨论】:

    • 另外(我使用 Chrome 的 Dev Http 客户端插件发现了这一点)SessionAuthentication 模块会进行引用检查,因此请确保您也设置了引用标题。
    • use HTTP_X_CSRFTOKEN, X-CSRFToken 适用于正常的 django 请求,但不适用于 django tastypie POSTPUT
    • 设置cookie后事件,angularjs中request.user为空 $http({ 'method': "POST", 'url': "localhost:8000/isAuthenticated_user", headers:{ "X-CSRFToken" : csrftoken, 'Content-Type': undefined // 'withCredentials':true }, })
    【解决方案2】:

    以下是对 Dan 回答的一些补充。如果有问题,请纠正我,我自己还是有点困惑。

    在我们继续之前,请阅读CSRF protection in Django仔细阅读。您需要将cookie中的令牌放入标头X-CSRFToken中。如果 cookie 是 Httponly,这将不起作用,也就是说,如果您在 settings.py 中设置了 CSRF-COOKIE-HTTPONLY = True。然后,您必须将 cookie 嵌入到文档中,这当然会产生更多漏洞并减少使用 Httponly 获得的保护。

    据我所知,如果 cookie 不是 HttponlyjQuery 会自动设置 X-CSRFToken。如果我错了,请纠正我,但我刚刚花了几个小时玩它,这就是我一直得到的。这让我想知道,Django 文档中的建议有什么意义?是 jQuery 的新特性吗?

    进一步讨论:

    Tastypie 禁用 CSRF 保护,但会话身份验证除外,它在 authentication.py 中有自定义代码。您必须同时传递 cookie csrftoken cookie 和标头 X-CSRFToken 才能进行身份验证。 (这是 Tastypie 的要求。)假设域相同,浏览器将传递 cookie。除非 csrftoken cookie 是 Httponly,否则 JQuery 将为您传递标头。相反,如果 cookie 是 Httponly,我什至无法在 $.ajaxSetup{beforeSend... 中手动设置标头。如果csrftoken cookie 是 Httponly,那么 jQuery 似乎会自动将 X-CSRFToken 设置为 null。至少我能够将标头 X-CS_RFToken 设置为我想要的,所以我知道我正确地传递了这个值。我正在使用 jQuery 1.10。

    如果您使用curl 进行测试,则必须传递两个cookie(sessionidcsrftoken),设置标头X-CSRFToken,如果协议是HTTPS,还要设置Referrer

    【讨论】:

      【解决方案3】:

      我在tastepie 源代码中找到了这个。基本上意味着 SessionAuthentication 不支持 HTTP POST。

      class SessionAuthentication(Authentication):
          """
          An authentication mechanism that piggy-backs on Django sessions.
      
          This is useful when the API is talking to Javascript on the same site.
          Relies on the user being logged in through the standard Django login
          setup.
      
          Requires a valid CSRF token.
          """
          def is_authenticated(self, request, **kwargs):
              """
              Checks to make sure the user is logged in & has a Django session.
              """
              # Cargo-culted from Django 1.3/1.4's ``django/middleware/csrf.py``.
              # We can't just use what's there, since the return values will be
              # wrong.
              # We also can't risk accessing ``request.POST``, which will break with
              # the serialized bodies.
              if request.method in ('GET', 'HEAD', 'OPTIONS', 'TRACE'):
                  return request.user.is_authenticated()
      

      所以在这里回答我自己的问题,但如果有人可以更好地解释它并提出一个好的方法来做到这一点,那也很棒。

      编辑

      我目前正在使用来自https://github.com/amezcua/TastyPie-DjangoCookie-Auth/blob/master/DjangoCookieAuth.py 的解决方法,它基本上是一种自定义身份验证方案,它从 cookie 中获取session_id 并检查后端是否已通过身份验证。可能不是最完整的证明解决方案,但效果很好。

      【讨论】:

      • 小而重要的更正:这确实暗示 SessionAuthentication 不支持 POST,它只是意味着对修改的方法将进行额外的检查(如 CSRF)数据(POST、PUT、DELETE 等)继续阅读该方法的其余部分并查看@dan-klasson 的答案,这是正确的......
      猜你喜欢
      • 2012-09-11
      • 1970-01-01
      • 2022-11-16
      • 1970-01-01
      • 2017-04-14
      • 2021-04-27
      • 2014-07-23
      • 1970-01-01
      • 2013-01-19
      相关资源
      最近更新 更多