Запросы Axios с использованием токена аутентификации иногда не работают в Safari

Я разрабатываю одностраничное приложение (16.9.0), которое использует axios (0.19.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: введите здесь описание изображения

Использование представлений API DRF основано на этом смешении:

class CommonViewSet(viewsets.ModelViewSet):
    authentication_classes = (TokenAuthentication, BasicAuthentication, SessionAuthentication)
    permission_classes = (IsAuthenticated,)

Для локальной разработки настройки CORS сервера DRF:

CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_HEADERS = [
    'accept',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
]

Я не понимаю, почему некоторые запросы в Safari не выполняются, а другие нет. В основном я хочу убедиться, что все запросы работают во всех трех браузерах.


person softweave    schedule 01.02.2020    source источник
comment
Пожалуйста, покажите пример вашего simplToken var и как вы его устанавливаете.   -  person mon io    schedule 02.02.2020
comment
Добавьте косую черту к URL-адресу запроса DELETE /apis/runs/43/ (СКОРНАЯ ЧАСТЬ В КОНЦЕ). Я думаю, проблема в том, что когда вы вызываете /apis/runs/43 (БЕЗ СКАСНОЙ ЧАСТИ), сафари перенаправляет вас правильно (на это с косой чертой), но без токена аутентификации в заголовке авторизации (заголовок не перенаправляется). Также Chrome делает то же самое, но перенаправляет заголовок авторизации.   -  person mon io    schedule 02.02.2020
comment
Ваше предложение решило проблему. Спасибо @mon io.   -  person softweave    schedule 03.02.2020


Ответы (2)


Решение состояло в том, чтобы добавить завершающую косую черту к URL-адресам, ссылающимся на один объект. В документах маршрутизатора DRF указан правильный шаблон:

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

Является ли это ошибкой или особенностью того, что Safari не включает токен аутентификации в перенаправленные запросы, что приводит к ошибке 401, я оставлю это читателю.

person softweave    schedule 03.02.2020
comment
Это была и моя проблема. Спасибо! - person Lewis Menelaws; 19.04.2020

Вы видели это? Я не совсем уверен, но это обсуждение может помощь.

Кроме того, поскольку ошибка связана с token, попробуйте проверить, правильно ли она отправлена ​​или добавлена ​​в запрос, или имеет ли она тип, например носитель или что-то в этом роде.

Также попробуйте записывать заголовки входящих запросов и их тело, чтобы убедиться, что ничего не пропало и не повреждено.

Поскольку эта проблема возникает с DELETE, попробуйте сравнить все запросы друг с другом, чтобы выяснить, чего не хватает.

person Mahmoud Adel    schedule 02.02.2020
comment
Спасибо за ответ. Я добавил сетевое ведение журнала Safari для удаления. Рассмотрю возможность добавления ведения журнала/отладки на стороне сервера. - person softweave; 02.02.2020
comment
Таким образом, вы сначала делаете запрос, затем получаете перенаправление, затем снова пытаетесь выполнить запрос без токена, а затем получаете несанкционированный ответ. Ну, для 3-го и 4-го запросов нет ничего плохого, нет токена с запросом на удаление, поэтому вы получаете авторизацию, но почему вы перенаправляетесь после первого запроса на первое место и почему запрос снова отправляется без токена. - person Mahmoud Adel; 02.02.2020
comment
попробуйте использовать сафари без расширений или с настройками по умолчанию или что-то в этом роде, возможно, есть что-то, из-за чего он так себя ведет - person Mahmoud Adel; 02.02.2020
comment
Я видел, но не понимал сетевой журнал Safari. Добавление косой черты к URL-адресу запроса на удаление решило проблему — и множество подобных проблем с URL-адресами на других страницах (например, GET /apis/runs/44/ ) - person softweave; 03.02.2020
comment
Это странно, на самом деле я впервые вижу это, это заставило меня искать больше о том, что на самом деле я не нашел много результатов, но это может добавить больше информации stackoverflow.com/questions/11348479/safari-adds-trailing-slash - person Mahmoud Adel; 03.02.2020
comment
Я хочу узнать об этом больше, так что добавили ли вы косую черту в конце URL-адреса axios, чтобы chrome и firefox игнорировали ее, а сафари ее использовало? или Вы добавили условие в случай handel safari? - person Mahmoud Adel; 03.02.2020
comment
Похоже, что косая черта в конце требуется сервером. Как показано в журналах сервера, которые я включил, и Safari, и Chrome должны были добавить косую черту к исходному URL-адресу. Однако Safari не удалось включить токен аутентификации при отправке перенаправленного запроса. После добавления завершающей косой черты к URL-адресам axios сервер немедленно принимает запрос. - person softweave; 03.02.2020
comment
Я знаю о завершающей косой черте в маршрутизаторе drf, я не упомянул об этом, потому что думал, что вы уже отключили ее, как обычно, косая черта не является обязательной или рекомендуемой или даже стандартной, это просто обычная вещь в Django. Это написано в документации маршрутизатора drf, которую вы включили. прочитайте раздел простого маршрутизатора django-rest-framework.org/api-guide /маршрутизаторы/#simplerouter - person Mahmoud Adel; 03.02.2020