【问题标题】:How to get the token with django rest framework and ajax如何使用 django rest 框架和 ajax 获取令牌
【发布时间】:2016-12-05 01:59:24
【问题描述】:

我想构建一个rest api,用户可以在其中使用令牌进行身份验证。我已将rest_framework.authtoken 包含在已安装的应用程序列表中。还在settings.py中添加了所需的配置:

INSTALLED_APPS = (
    ...
    'rest_framework.authtoken'
)

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    )
}

定义了一种方法来监听post_save 信号并为新创建的用户创建新令牌。然后我做了迁移。创建新用户后,我可以看到该用户的令牌。

如果我这样做了

http POST 0.0.0.0:80/api-token-auth/ username='user@gmail.com' password='secure123'

我收到了回复

HTTP/1.0 200 OK
Allow: POST, OPTIONS
Content-Type: application/json
Date: Sat, 30 Jul 2016 12:05:30 GMT
Server: WSGIServer/0.1 Python/2.7.3
Vary: Cookie
X-Frame-Options: SAMEORIGIN

{
    "token": "4aecfb249265064c55300d782e4c7e66b8b77063"
}

所以我想它的工作原理。但如果我尝试使用 ajax 登录:

$.ajax({
    url: 'http://test.com/api-token-auth/ username=' + email + ' password='+ password,
    dataType: 'json',
    cache: false,
    success: function(data) {
        console.log(data);
    }.bind(this),
    error: function(xhr, status, err) {
        console.log(err);
    }.bind(this)
});

我在浏览器控制台中收到此错误:

jquery-3.1.0.min.js:4 GET http://test.com/api-token-auth/%20username=user@gmail.com%20password=secure123?_=1469883569618 405(不允许的方法)

bundle.js:27453 方法不允许

如何获取经过身份验证的用户的令牌,以便我可以使用它作为经过身份验证的用户发布?

更新

我也在使用django-cors-headers 来处理与 CORS 相关的问题。

更新

%20username=user@gmail.com%20password=secure123?_=1469885103431 405 xhr jquery-3.1.0.min.js:4   278 B   29 ms   

更新:添加响应标头

【问题讨论】:

  • 提供浏览器网络通信的详细信息,在 Chrome 中,您可以在调试器的网络选项卡中找到它
  • @shacki 添加了详细信息。请看一看。
  • %20 表示空格,在您的 ajax 请求中,将 'username' 替换为 '?username' 和 'password' 到 '&password'。我还记得这也需要 '&grant_type=password' 参数。请求 url 中不能有空格 (' ')。

标签: python ajax django rest django-rest-framework


【解决方案1】:

默认情况下,typemethod 值在 jQuery.ajax() 方法上设置为 'GET'。它看起来像您得到的响应,只允许“POST”和“OPTIONS”。

您如何尝试在您的 jQuery.ajax() 方法上将 typemethod 值设置为 'POST'。

【讨论】:

  • 添加method='POST' 后,出现此错误:jquery-3.1.0.min.js:4 POST http://test.com/api-token-auth/%20username=user@gmail.com%20password=secure123 400 (Bad Request)
  • 你能通过响应头吗?
  • 用响应头更新了问题。请看一看。
  • 您是否更改了 jQuery.ajax() 方法的设置,以便在每个 POST 请求中将 CSRF 令牌作为 POST 数据传递?这是任何“不安全”的 HTTP 方法调用所必需的,例如 PUT、PATCH、POST 或 DELETE 请求。
【解决方案2】:

这是一个 cors 问题,尝试使用 Chromium 并使用 chromium-browser --disable-web-security 启动它来测试它

【讨论】:

    【解决方案3】:

    这里的问题是因为您不是将数据发送到请求负载中,而是通过 URL 传递,就像 GET 请求一样。

    您使用httpie 生成的请求有效,因为它正确地生成了请求,如您所见:

    请求:

    http POST 0.0.0.0:80/api-token-auth/ username='user@gmail.com' password='secure123'
    

    请求(详细模式):

    POST /api-token-auth/ HTTP/1.1
    Accept: application/json
    Accept-Encoding: gzip, deflate
    Connection: keep-alive
    Content-Length: 55
    Content-Type: application/json
    Host: 0.0.0.0:8000
    User-Agent: HTTPie/0.9.3
    
    {
        "password": "secure123",
        "username": "user@gmail.com"
    }
    

    不同于:

    请求:

    http POST "0.0.0.0:8000/api-token-auth/ username='user@gmail.com' password='secure123'"
    

    请求(详细模式):

    POST /api-token-auth/%20username='user@gmail.com'%20password='secure123' HTTP/1.1
    Accept: */*
    Accept-Encoding: gzip, deflate
    Connection: keep-alive
    Content-Length: 0
    Host: 0.0.0.0:8000
    User-Agent: HTTPie/0.9.3
    

    你可以试试这个例子我发现here 如何使用 jQuery 以正确的方式发送数据。 (我没有测试它。)

    $.ajax({
        type: "POST",
        url: "/api/articles/",
        data: JSON.stringify(data),
        sucess: function() { console.log("Success!"); },
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        crossDomain:false,
        beforeSend: function(xhr, settings) {
          xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
    });
    

    【讨论】:

      【解决方案4】:

      如果您在浏览器中使用经过身份验证的用户,则可以从 cookie 中获取令牌。

      const csrftoken = Cookies.get('csrftoken');

      来自:https://docs.djangoproject.com/en/4.0/ref/csrf/#ajax

      【讨论】:

      • 注意:这是部分答案。如果有人可以提供有关未托管在浏览器中的客户端如何获取令牌的参考,那就太好了。
      猜你喜欢
      • 2016-06-23
      • 2018-05-15
      • 2017-01-25
      • 1970-01-01
      • 2013-01-28
      • 2023-03-29
      • 2020-07-16
      • 2021-08-03
      • 2016-08-12
      相关资源
      最近更新 更多