Почему метод jaquery .ajax () не отправляет мой сеансовый cookie?

256

После входа в систему через $.ajax() на сайт, я пытаюсь отправить второй запрос $.ajax() на этот сайт, но когда я проверяю заголовки, отправленные с использованием FireBug, в запрос не входит cookie сеанса.

Что я делаю неправильно?

  • 2
    Файл cookie ajax может появиться после веб-файла cookie, и FireBug может перехватить файл cookie первой страницы.
  • 1
    Я не понял, что вы имеете в виду, но я могу сказать, если я вставлю URL-адрес запроса в адресную строку браузера и снова проверю Firebug, я могу увидеть cookie в заголовках, отправленных на сервер. Какие-либо решения?
Показать ещё 5 комментариев
Теги:
cookies
session

9 ответов

175
Лучший ответ

AJAX вызывает только отправку Cookies, если адрес, который вы вызываете, находится в том же домене, что и ваш вызов script.

Это может быть проблема с перекрестными доменами.

Возможно, вы пытались вызвать URL-адрес от www.domain-a.com, пока ваш вызов script был включен www.domain-b.com (другими словами: вы сделали перекрестный доменный вызов, и в этом случае браузер не отправит файлы cookie для защиты ваших неприкосновенность частной жизни).

В этом случае ваши варианты:

  • Напишите небольшой прокси-сервер, который находится на домене-b и перенаправляет ваши запросы в домен-a. Ваш браузер позволит вам вызвать прокси-сервер, потому что он находится на том же сервере, что и вызывающий script.
    Затем этот прокси-сервер может быть настроен вами, чтобы принять имя и значение файла cookie, которое он может отправить в домен-a, Но для этого вам нужно знать имя файла cookie и значение вашего сервера в домене - требуется для аутентификации.
  • Если вы извлекаете объекты JSON, попробуйте вместо этого использовать JSONP. jQuery поддерживает их. Но вам нужно изменить свою службу на домене-a, чтобы он возвращал действительные ответы JSONP.

Рад, если это помогло даже немного.

  • 16
    Также стоит отметить, что файлы cookie могут быть установлены по определенному пути, поэтому, если для файла cookie задан path=/something и вы запрашиваете страницу /another файл cookie не будет отправлен. Когда вы запрашиваете страницу /something то, куки будут отправлены, как ожидалось. Так что проверьте код, который также устанавливает cookie.
  • 2
    JSONP-запрос отправляет куки?
Показать ещё 6 комментариев
302

Я работаю в междоменном сценарии. Во время входа в систему удаленный сервер возвращает заголовок Set-Cookie, а Access-Control-Allow-Credentials - true.

Следующий вызов ajax для удаленного сервера должен использовать этот файл cookie.

CORS Access-Control-Allow-Credentials позволяет выполнять междоменное протоколирование. Для примера рассмотрите https://developer.mozilla.org/En/HTTP_access_control.

Для меня это похоже на ошибку в JQuery (или, по крайней мере, функцию, которая будет в следующей версии).

UPDATE:

ОТВЕТ: Вы должны использовать xhrFields param http://api.jquery.com/jQuery.ajax/

Пример в документации:

$.ajax({
   url: a_cross_domain_url,
   xhrFields: {
      withCredentials: true
   }
});

Важно также, чтобы сервер правильно ответил на этот запрос. Копирование здесь замечательных комментариев от @Frédéric и @Pebbl:

Important note: when responding to a credentialed request, server must specify a domain, and cannot use wild carding. The above example would fail if the header was wildcarded as: Access-Control-Allow-Origin: *

Итак, когда запрос:

Origin: http://foo.example
Cookie: pageAccess=2

Сервер должен ответить:

Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Credentials: true

[payload]

В противном случае полезная нагрузка не будет возвращена на script. См.: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials

  • 7
    Большой ! Я добавляю для использования этого + установить заголовок Access-Control-Allow-Credentials в true на стороне сервера
  • 0
    и где я могу установить эти учетные данные ?, при авторизации заголовка ?, в теле запроса?
Показать ещё 6 комментариев
35

Использование

xhrFields: { withCredentials:true }

как часть моего jQuery ajax-вызова была только частью решения. Мне также нужно было вернуть заголовки в ответ OPTIONS от моего ресурса:

Access-Control-Allow-Origin : http://www.wombling.com
Access-Control-Allow-Credentials : true

Важно, чтобы в заголовке ответа вызова OPTIONS разрешалось только one и не "*". Я достиг этого, прочитав исходный код из запроса и заполнив его обратно в ответ - возможно, обойти первоначальную причину ограничения, но в моем случае защита не имеет первостепенной важности.

Я подумал, что стоит явно упомянуть о требовании только для одного источника, поскольку стандарт W3C позволяет использовать список, разделенный пробелом, - но Chrome не делает этого! http://www.w3.org/TR/cors/#access-control-allow-origin-response-header NB бит "на практике".

29

Поместите это в свою функцию init:

$.ajaxSetup({
  xhrFields: {
    withCredentials: true
  }
});

Он будет работать.

  • 1
    Вы спасли мой день! На уровне метода withCredentials у меня не работает. Но глобально, как это, это, наконец, работает! Благодарю.
8

Уже есть много хороших ответов на этот вопрос, но я подумал, что может быть полезно прояснить случай, когда вы ожидаете, что cookie сеанса будет отправлен, потому что домен cookie совпадает, но он не отправляется, поскольку Запрос AJAX делается для другого субдомена. В этом случае у меня есть файл cookie, который присваивается домену *. Mydomain.com, и я хочу, чтобы он был включен в запрос AJAX для different.mydomain.com ". По умолчанию cookie не отправляется. Вам не нужно отключать HTTPONLY в cookie сеанса, чтобы решить эту проблему. Вам нужно только сделать то, что предложили махровые (https://stackoverflow.com/questions/2870371/why-is-jquerys-ajax-method-not-sending-my-session-cookie) и выполните следующие действия.

1) Добавьте в свой запрос ajax следующее.

xhrFields: { withCredentials:true }

2) Добавьте в свои заголовки ответов следующие ресурсы для ресурсов в разных субдоменах.

Access-Control-Allow-Origin : http://original.mydomain.com
Access-Control-Allow-Credentials : true
3

У меня была такая же проблема, и некоторые проверки мои script просто не получали cookie sessionid.

Я понял, посмотрев значение cookie sessionid в браузере, которое моя инфраструктура (Django) передавала cookie sessionid с HttpOnly по умолчанию. Это означало, что скрипты не имели доступа к значению sessionid и поэтому не передавали его вместе с запросами. Вид смешного, что HttpOnly будет значением по умолчанию, когда так много вещей использует Ajax, для которого требуется ограничение доступа.

Чтобы исправить это, я изменил настройку (SESSION_COOKIE_HTTPONLY = False), но в других случаях это может быть флаг HttpOnly на пути к файлу cookie

  • 0
    blog.codinghorror.com/protecting-your-cookies-httponly
  • 1
    Не делайте этого. Это позволяет клиентскому сценарию получить доступ к сессионному cookie, который является наиболее распространенным вектором атаки XSS. owasp.org/index.php/HttpOnly
1

Вы должны инициализировать сеанс перед попыткой входа в систему.

Для php вам нужно сделать

session_start();

на странице с того места, где вы запустите вход в систему ajax.

Итак, SESSIONID будет создан и сохранен cookie браузера. И отправляется вместе с заголовком запроса во время вызова ajax, если вы выполняете запрос ajax в тот же домен

Для последовательных вызовов ajax браузер будет использовать SESSIONID, который был создан и сохранен первоначально в cookie браузера, если мы не очистим cookie браузера или не выйдем из системы (или не установим другой файл cookie)

0

Если вы разрабатываете на localhost или порт на localhost, например localhost:8080, в дополнение к шагам, описанным в ответах выше, вам также необходимо убедиться, что вы не передаете значение домена в Set- Заголовок файла cookie.
Вы не можете установить домен в localhost в заголовке Set-Cookie - это неверно - просто опустите домен.

Смотрите Куки файлы на локальном хосте с явным доменом и Почему asp.net не создает файлы cookie в localhost?

  • 0
    Можете ли вы показать пример кода
-4

Возможно, не 100% ответив на вопрос, но я наткнулся на этот поток в надежде решить проблему сеанса, когда ajax-posting fileupload от управляющего ресурсами редактора innovastudio. В конце концов решение было простым: у них есть флеш-загрузчик. Отключение этого (установка

var flashUpload = false;   

в файле asset.php), и свет снова начал мигать.

Поскольку эти проблемы могут быть очень трудными для отладки, я обнаружил, что в обработчике загрузки будет добавлено что-то вроде следующего: вы, ну, в данном случае, установите нужный трек:

$sn=session_name();
error_log("session_name: $sn ");

if(isset($_GET[$sn])) error_log("session as GET param");
if(isset($_POST[$sn])) error_log("session as POST param");
if(isset($_COOKIE[$sn])) error_log("session as Cookie");
if(isset($PHPSESSID)) error_log("session as Global");

Погрузитесь в журнал, и я быстро заметил отсутствующий сеанс, где не было отправлено ни одного файла cookie.

  • 0
    Я не думаю, что приведенный выше пример будет работать, потому что, если нет файла cookie сеанса, каким будет значение $ sn? (случайный или, может быть, ноль), в качестве альтернативы пользователи могут установить session_name из значения GET, например session_name(isset($_GET['sess']) ? $_GET['sess'] : null);session_start(); таким образом, они получили бы рабочую вещь
  • 0
    Это именно то, как я нашел проблему: нет сессий при публикации из этого Flash Uploader вещь. Поскольку использование идентификатора сеанса переменной GET - плохая идея, и cookie не работает, я его выбросил. Кого волнует, вспышка остается в прошлом в любом случае.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню