Я отправляю это по дороге домой, так что извините за отсутствие кода, но я постараюсь быть максимально подробным и добавить код, когда смогу сегодня вечером.Так что, по сути, у меня есть встроенное приложение с использованием приставки и аксиоса.Краткий обзор (следующий код) может объяснить, что я делаю что-то не так.
Serviceapi.js Создает и экспортирует базовые аксио с базовым URL.
const ServiceApi = axios.create({
baseURL: BASE_URL,
responseType: 'json'
});
AuthReducer.js При входе в систему устанавливает заголовок авторизации вручную, используя метод post.Это работает как на Android, так и на IOS, логин возвращается, и я использую заголовок авторизации.
return {
type: PERFORM_LOGIN,
payload: {
user: {
name: username
},
request: {
url: '/login',
method: 'post',
headers: {
'Authorization': 'Basic ' + basicAuth
}
}
}
При входе в систему я возвращаю следующее действие redux-axios, вы можете видеть, что я установил заголовок: Авторизация вручную, это прекрасно работает.
// On login success, set the authInterceptor responsible for adding headers
authInterceptor = ServiceApi.interceptors.request.use((config) => {
console.log(`Attaching Authorization to header ${basicAuth}`);
config.headers.common.Authorization = basicAuth;
return config;
}, (error) => {
Promise.reject(error);
});
При выходе я очищаюперехватчикЯ решил добавить и удалить при входе и выходе из системы, вместо того, чтобы всегда иметь его там только потому, что.Это может быть проблемой, но это нормально для Android
// Clear the auth interceptor
ServiceApi.interceptors.request.eject(authInterceptor);
Опять же, все это прекрасно работает на Android.И, похоже, работает на IOS.Когда я отлаживаю перехватчик, он вызывается и устанавливает заголовок.
Но я получаю 403 на ios.После более детального изучения запроса, существует большая разница между заголовком android в запросе и заголовком ios в запросе.Остальная часть объекта запроса такая же, только объект _header отличается между ios и android.
Запрос Android
_headers:
accept: "application/json, text/plain, */*"
authorization: "Basic <correct base64 value>"
content-type: "application/json;charset=utf-8"
__proto__: Object
Запрос IOS
_headers:
accept: (...)
authorization: (...)
content-type: (...)
get accept: ƒ ()
set accept: ƒ ()
get authorization: ƒ ()
set authorization: ƒ ()
get content-type: ƒ ()
set content-type: ƒ ()
__proto__: Object
С учетом различий, устанавливая точку останова при взгляде на консоль для error.request._headers.authorization;
, я получаю такое же содержимое "Basic:", как в заголовке Android.
index.php Бэкэнд-сервис - это php-файл, который выполняет $ _SERVER ['PHP_AUTH_USER'], который завершается с ошибкой 403, если не установлен, что и происходит.У меня нет доступа к php, мне просто сказали, что это то, что он использует.
Снова прошу прощения за то, что не предоставил код, но сделаю это, когда у меня появится шанс позжеЕсть ли что-то, может быть, я должен установить дополнительные для IOS?Или, может быть, php для ios нужен дополнительный заголовок?
Код для подражания.
РЕДАКТИРОВАТЬ Обновлено с кодом, надеюсь, я не оставил ни одной из закодированных данных для входа.
РЕДАКТИРОВАТЬ 2 При дальнейшем изучении это выглядит так, как будто это связано с apache / PHP, а не реагирующе-родным / axios.Я собрал экспресс-сервер, который имитировал ту же проверку, что и PHP: - Ищите заголовок авторизации - Распечатайте его - Верните обратно 403 или 200 с данными на основе этого
При запуске, указывая на http://localhost:3000 используя то же самое приложение на эмуляторе, я получаю то, что ожидаю.Чтобы добавить к этому, когда я на эмуляторе, я не могу войти в систему по действующему URL (даже если бы я мог на обычном устройстве), я получаю ту же ошибку 403, но на этот раз немного раньше.
РЕДАКТИРОВАТЬ 3
Чтобы предоставить больше информации с сервера, вот три запроса, которые мне удалось зарегистрировать:
1) Этоиз эмулятора IOS iPhone8 против экспресс-сервера:
accept:"application/json, text/plain, */*"
accept-encoding:"gzip, deflate"
accept-language:"en-us"
authorization:"Basic <base 64 encoding>"
connection:"keep-alive"
content-length:"0"
host:"localhost:3000"
user-agent:"MobileApp/1 CFNetwork/978.0.7 Darwin/18.5.
2) Это из того же эмулятора, что и apache / PHP (5.3.3), мы видим, что заголовок авторизации отсутствует.
Accept: application/json, text/plain, */*
User-Agent: MobileApp/1 CFNetwork/978.0.7 Darwin/18.5.0
Accept-Language: en-us
Accept-Encoding: br, gzip, deflate
Connection: keep-alive
3) Это от Android до apache / PHP (5.3.3):
authorization: Basic <Base 64 encoding>
Host: api.serviceurl.com
Connection: Keep-Alive
Accept-Encoding: gzip
User-Agent: okhttp/3.12.1
Редактировать 4 Так что, поиграв и погуглив некоторое время,Оказывается, проблема в Zend Framework и fastcgi, который автоматически удаляет заголовок авторизации.Странно то, что он делает это только с IOS, а не с Android, что на самом деле не имеет смысла.
В журналах мы заметили, что он принимает Android и Postman как POST, но регистрирует запросы IOS как GET.Я не совсем уверен, что с этим, но, похоже, это другое отличие.Я обновил задачу, чтобы Zend был тегом.Существует множество статей по решению этой проблемы с помощью ReWriteMod на apache / zend, поэтому сначала я опробую их и посмотрю, решит ли это проблему.
** Edit 5 ** Пока что мыпопытался следовать статьям SO, которые просят добавить следующее: ( отсутствует заголовок авторизации в django rest_framework, виноват apache? ):
SetEnvIfNoCase Authorization ^(.*) -e=PHP_HTTP_AUTH
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
, что приводит к следующему:
// IOS
_SERVER[PHP_HTTP_AUTH] = <blank>
_SERVER[HTTP_AUTHORIZATION] = <blank>
// Android
_SERVER[PHP_HTTP_AUTH] = Username
_SERVER[HTTP_AUTHORIZATION] = Basic <Base65 encoded>
_SERVER[PHP_HTTP_PW] = Password
Итак, мы знаем, что авторизация заголовка доходит до Apache, но теперь она проходит как пустая.Есть несколько других ответов SO, которые я исследую, но поиск продолжается ...
Редактировать 6
Resolved (ish)