Django rest framework 在Safari中,使用身份验证令牌的Axios请求有时会失败

Django rest framework 在Safari中,使用身份验证令牌的Axios请求有时会失败,django-rest-framework,safari,axios,django-rest-auth,Django Rest Framework,Safari,Axios,Django Rest Auth,我正在开发使用axios(0.19.0)的react(16.9.0)单页应用程序。axios请求使用令牌身份验证来访问运行django rest framework(3.6.4)和django cors标头(3.1.1)的服务器。身份验证令牌由django rest auth(0.9.5)在登录期间生成 该应用程序在Chrome和Firefox中运行可靠。在Safari中,一些请求由于401错误而失败 此请求在所有三种浏览器中都会成功: INFO basehttp: "GET /apis/gam

我正在开发使用axios(0.19.0)的react(16.9.0)单页应用程序。axios请求使用令牌身份验证来访问运行django rest framework(3.6.4)和django cors标头(3.1.1)的服务器。身份验证令牌由django rest auth(0.9.5)在登录期间生成

该应用程序在Chrome和Firefox中运行可靠。在Safari中,一些请求由于401错误而失败

此请求在所有三种浏览器中都会成功:

INFO basehttp: "GET /apis/games/?slug=pop HTTP/1.1" 200 60932```
生成它的代码如下所示:

    axios
      .get(`${simplUrl}/apis/games/?slug=${gameSlug}`, {
        headers: { Authorization: simplToken },
      })
      .then(res => {
        this.setState({
          game: res.data[0],
        });
      ...
      const url = `${simplUrl}/apis/runs/${run.id}`;
      // console.log('url:', url);
      axios
        .delete(url, {
          headers: { Authorization: simplToken },
        })
        .then(res => {
          // console.log(res);
          afterDelete();
        });
此请求在Safari中失败:

INFO basehttp: "OPTIONS /apis/runs/43 HTTP/1.1" 200 0
INFO basehttp: "DELETE /apis/runs/43 HTTP/1.1" 301 0
INFO basehttp: "OPTIONS /apis/runs/43/ HTTP/1.1" 200 0
WARNING basehttp: "DELETE /apis/runs/43/ HTTP/1.1" 401 58
但是Chrome成功了:

INFO basehttp: "OPTIONS /apis/runs/43 HTTP/1.1" 200 0
INFO basehttp: "DELETE /apis/runs/43 HTTP/1.1" 301 0
INFO basehttp: "OPTIONS /apis/runs/43/ HTTP/1.1" 200 0
INFO basehttp: "DELETE /apis/runs/43/ HTTP/1.1" 204 0
生成它的代码如下所示:

    axios
      .get(`${simplUrl}/apis/games/?slug=${gameSlug}`, {
        headers: { Authorization: simplToken },
      })
      .then(res => {
        this.setState({
          game: res.data[0],
        });
      ...
      const url = `${simplUrl}/apis/runs/${run.id}`;
      // console.log('url:', url);
      axios
        .delete(url, {
          headers: { Authorization: simplToken },
        })
        .then(res => {
          // console.log(res);
          afterDelete();
        });
Safari 401的回应是:

"detail": "Authentication credentials were not provided."
这是Safari为失败的删除请求记录的信息:

DRF API视图的使用基于以下混合:

class CommonViewSet(viewsets.ModelViewSet):
    authentication_classes = (TokenAuthentication, BasicAuthentication, SessionAuthentication)
    permission_classes = (IsAuthenticated,)
对于本地开发,DRF服务器的CORS设置为:

CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_HEADERS = [
    'accept',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
]
我不明白为什么有些请求在Safari中失败,而另一些则没有。大多数情况下,我希望确保所有请求在所有三种浏览器中都能正常工作。

您看到了吗?,我不太确定,但这一讨论可能会有所帮助

此外,由于错误与
令牌相关,请尝试验证其是否已正确发送或添加到请求中,或者是否具有类似于bearer或somthing的类型

还要尝试记录传入的请求头及其主体,以便确保没有任何内容丢失或损坏


由于此问题发生在
DELETE
中,请尝试将所有请求相互重叠,以找出缺少的内容。

解决方案是在引用单个对象的URL中添加一个尾随斜杠。指示正确模式的参数为:

URL pattern: ^users/{pk}/$ Name: 'user-detail'

无论是错误还是Safari未在重定向请求中包含身份验证令牌的功能导致401错误,我将留给读者。

请展示“SimpleToken”变量的示例以及如何设置。将斜杠添加到删除请求url/API/runs/43/(结尾的斜杠)。我认为问题在于,当您调用/api/runs/43(不带斜杠)时,safari会正确地重定向您(带斜杠)到这个位置,但在授权头中没有auth标记(头不会被转发)。chrome也做了同样的事情,但是它重定向了授权头。你的建议解决了这个问题。谢谢@mon io。谢谢你的回复。我为删除添加了Safari的网络日志。将研究添加服务器端日志记录/调试。因此,首先执行请求,然后重定向,然后尝试在没有令牌的情况下再次执行请求,然后获得未经授权的响应。好吧,对于第三次和第四次请求没有问题,删除请求没有令牌,因此您会被授权,但是为什么在第一次请求之后您会在第一个位置被重定向,为什么请求会在没有令牌的情况下再次发送。尝试使用safari而不使用扩展或默认设置或其他方式,也许有什么原因使它行为不端,就像我看到但不理解Safari的网络日志一样。在删除请求url中添加斜杠解决了这个问题——其他页面上也出现了许多类似的url问题(例如“GET/api/runs/44/)。这很奇怪,事实上这是我第一次看到这一点,这促使我搜索更多关于这一点的内容,实际上我没有找到多少结果,但这可能会添加更多信息。这也是我的问题。谢谢!