使用身份验证令牌的 Axios 请求有时在 Safari 中失败

Axios requests using authentication token sometimes fail in Safari

我正在开发一个使用 axios (0.19.0) 的 React (16.9.0) 单页应用程序。 axios 请求使用令牌身份验证来访问服务器 运行 django-rest-framework (3.6.4) 和 django-cors-headers (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],
        });
      ...

此请求在 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

生成它的代码如下所示:

      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 为失败的 DELETE 请求记录的信息:

使用的 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 中会失败,而有些则不会。大多数情况下,我想确保所有请求在所有三种浏览器中都能正常工作。

你看到 this 了吗?我不太确定,但这个讨论可能会有帮助。

此外,由于错误与 token 有关,请尝试验证它是否已正确发送或添加到请求中,或者它是否具有承载或其他类型。

同时尝试记录传入的请求 headers 及其 body,这样您就可以确保没有任何内容丢失或损坏。

由于 DELETE 会出现此问题,请尝试相互比较所有请求以找出缺少的内容。

解决方案是在引用单个对象的 URL 中添加尾部斜杠。 DRF Router docs 表示正确的模式是:

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

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