Подтвердить что ты не робот

Учетные данные CORS cookie из мобильного WebView загружаются локально с файлом://

Потерпите меня, вам нужно немного объяснения.

Я помогаю построить гибридное мобильное веб-приложение. Основной кодовой базой является HTML5 и JavaScript, которые будут обернуты в собственный мобильный веб-просмотр (a la Phonegap).

Частичная функциональность требует, чтобы приложение отправляло информацию в веб-службу, контролируемую одним из наших клиентов. Существует очень мало возможностей для изменения этого веб-сервиса, поскольку он используется другими. Мы отправляем JSON с помощью HTTP POST и получаем ответы с сервера. Часть этого ответа представляет собой файл cookie JSESSIONID, который управляет нашей сессией с сервером. После первоначального вызова initSession() нам необходимо отправить файл cookie JSESSIONID с каждым запросом (AJAX).

При развертывании на мобильном устройстве веб-приложение завершается в собственном веб-представлении, которое запускает веб-приложение, просматривая file:///path/to/app/index.html.

Первое, что мы попробовали, - попросить нашего клиента установить Access-Control-Allow-Origin: * в заголовке ответа, чтобы разрешить CORS. Затем мы попытались отправить сообщение на сервер:

$.ajax({
  url: 'http://thirdparty.com/ws',
  data: data,
  type: "POST",
  dataType: "JSON",
  success: successCallback,
  error: failedCallback
});

Наблюдая за запросами, было очевидно, что файлы cookie не включены. При ближайшем рассмотрении есть специальный раздел в спецификации CORS для учета учетных данных пользователя, который включает файлы cookie сеанса. Поэтому я изменил вызов AJAX, чтобы включить это:

$.ajax({
  url: 'http://thirdparty.com/ws',
  data: data,
  type: "POST",
  dataType: "JSON",
  success: successCallback,
  error: failedCallback,
  xhrFields { withCredentials: true }
});

Другая ошибка, на этот раз из браузера. Более подробное чтение дало следующее:

Если сторонний сервер не ответил заголовком Access-Control-Allow-Credentials: true, ответ будет проигнорирован и не будет доступен для веб-контента.

Важное примечание: при ответе на запрашиваемый запрос сервер должен указать домен в заголовке Access-Control-Allow-Origin и не может использовать wild carding.

Поэтому нам нужно изменить заголовки серверов, чтобы включить Access-Control-Allow-Credentials: true и Access-Control-Allow-Origin в наш Origin.

Здесь мы, наконец, приходим к моей проблеме: при загрузке веб-страницы с использованием протокола file://, заголовок запроса Origin, отправленный из веб-представления, установлен на null. Поэтому он не может быть проанализирован сервером, поэтому сервер не может установить его в Access-Control-Allow-Origin. Но если сервер не может установить Access-Control-Allow-Origin на нечто иное, чем *, мы не можем отправлять учетные данные, включая файлы cookie.

Итак, я застрял. Что делать? Я видел аналогичный вопрос, размещенный здесь, но я не совсем понимаю предлагаемый ответ. Любая помощь приветствуется!

4b9b3361

Ответ 1

Я понимаю, что этот вопрос устарел, но я подумал, что все равно набросись на него. В случае запросов CORS браузер запускает их. Это означает, что - несмотря на любой метод $.ajax(), который вы используете, на сервер отправляется запрос OPTIONS.

В этом предпродажном запросе OPTIONS говорится:

"Эй, чужой сервер-от-другого-домена, я хочу отправить вам непростой запрос (простой запрос не предваряется). Мой непростой запрос будет иметь такие заголовки и тип контента и т.д. Можете ли вы сообщить мне, если все в порядке?"

Затем сервер будет делать все, что он делает (возможно, проверяет какую-либо конфигурацию или базу данных) и отвечает разрешенным источником (-ами), допустимым заголовком (-ами) и/или допустимым (ыми) методом (-ами).

Наконец - если этот запрос preflight OPTIONS получил ответ, который позволяет фактическому методу $.ajax() идти - он идет.

CORS не то же самое, что JSONP.

Все сказанное - в то время как withCredentials успех перед полетом требует ответа на перенос заголовка Access-Control-Allow-Credentials (как указано в вопросе), то есть IN ДОБАВЛЕНИЕ к значениям Access-Control-Allow-Origins И Access-Control-Allow-Methods, которые должны включать в себя грани от предполагаемого запроса.

Например, если вы делаете запрос CORS POST из источника http://foo-domain.com с заголовками somevalue до http://bar-domain.com, запрос preflight OPTIONS погаснет и для того, чтобы фактический пост-запрос был сделанный в http://bar-domain.com, запрос OPTIONS должен был бы получить ответ со значением Access-Control-Allow-Origins, который включал http://foo-domain.com. Это может быть имя самого начала или *. Ответ также должен иметь значение Access-Control-Allow-Methods, которое включало POST. Это также может быть *. И, наконец, если мы хотим, чтобы наш заголовок somevalue был разрешен, ответ должен содержать значение Access-Control-Allow-Headers, которое включает наш заголовок somevalue или *.

Чтобы повернуть назад - если вы не можете управлять сервером или не имеете возможности разрешить серверу разрешать ваши запросы CORS, вы всегда можете использовать JSONP или некоторый тип urlEncoded и/или делать простые запросы без пользовательских заголовков. GET, HEAD, а полные запросы POST обычно являются простыми запросами.

Ответ 2

Я предполагаю, что если вы создаете гибридное приложение, вы используете кордову. Если это так, вам не нужно CORS, вам просто нужно, чтобы белый список доменов, к которым вы хотите получить доступ.

http://docs.phonegap.com/en/3.0.0/guide_appdev_whitelist_index.md.html

Ответ 3

Мое предложение установлено ACCESS-CONTROL-ALLOW-ORIGIN на null на стороне сервера

Да, этот вопрос меня немного беспокоит.

Относительно CORS spec, null может удовлетворить ситуацию, когда запрос CORS из схемы file://

И пратическая рекомендация по этой спецификации заключается в том, чтобы установить ее как origin-list-or-null, которая является либо списком пространственно- разделенное происхождение или просто "нуль" (кстати, строка %x6E %x75 %x6C %x6C из определения для origin-list-or-null буквально null hex-encoded)

Наконец, вы спросите, не будет ли это равным *, если мы установим ACCESS-CONTROL-ALLOW-ORIGIN в null, так как каждый запрос из схемы file:// действителен (это означает, что каждое гибридное приложение может получить доступ к вашей конечной точке, если оно знает о вашем URI)?

Ну, учитывая Access-Control-Allow-Credentials: true, я считаю, что на сервере работает целый механизм аутентификации. Он должен был отфильтровать эти запросы без правильного авторизации

Надеюсь, что это поможет

Ответ 4

Попробуйте посмотреть на www.5app.co.uk. Исключает использование вызовов XHR в целом и надежно работает на мобильных устройствах, когда происходит соединение данных. Затем Gateway взаимодействует с вашим клиентом.

Ответ 5

Использовать запрос JsonP. Запрос JsonP позволяет выполнять запрос перекрестного домена. Вот пример.