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

Терпите меня, это нужно немного объяснить.

Я помогаю создавать гибридное мобильное веб-приложение. Основная кодовая база - это HTML5 и JavaScript, которые будут обёрнуты в собственное мобильное веб-представление (как 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 есть специальный раздел для работы с учетными данными пользователя , который включает куки-файлы сеанса. Поэтому я изменил вызов 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 и не может использовать групповые символы.

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

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

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

Ответы [ 6 ]

7 голосов
/ 14 апреля 2014

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

На самом деле этот предварительный OPTIONS запрос говорит:

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

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

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

CORS отличается от JSONP.

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

Например - если вы делаете запрос CORS POST из источника http://foo-domain.com с заголовками somevalue до http://bar-domain.com, запрос предполетного 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 голосов
/ 13 марта 2014

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

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

1 голос
/ 23 апреля 2015

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

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

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

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

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

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

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

0 голосов
/ 18 июля 2018

Например, на стороне php вам нужно установить следующее:

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, Accept, Authorization, X-Request-With, Set-Cookie, Cookie, Bearer');
header('Access-Control-Allow-Credentials: true');
// header('Cookie: PHPSESSID='.$_COOKIE['PHPSESSID']);
0 голосов
/ 19 марта 2014

Используйте запрос JsonP. Запрос JsonP позволяет выполнять междоменный запрос. Здесь является примером.

0 голосов
/ 19 февраля 2012

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

...