После входа в систему через $.ajax()
на сайт, я пытаюсь отправить второй запрос $.ajax()
на этот сайт, но когда я проверяю заголовки, отправленные с использованием FireBug, в запрос не входит cookie сеанса.
Что я делаю неправильно?
После входа в систему через $.ajax()
на сайт, я пытаюсь отправить второй запрос $.ajax()
на этот сайт, но когда я проверяю заголовки, отправленные с использованием FireBug, в запрос не входит cookie сеанса.
Что я делаю неправильно?
AJAX вызывает только отправку Cookies, если адрес, который вы вызываете, находится в том же домене, что и ваш вызов script.
Это может быть проблема с перекрестными доменами.
Возможно, вы пытались вызвать URL-адрес от www.domain-a.com
, пока ваш вызов script был включен www.domain-b.com
(другими словами: вы сделали перекрестный доменный вызов, и в этом случае браузер не отправит файлы cookie для защиты ваших неприкосновенность частной жизни).
В этом случае ваши варианты:
Рад, если это помогло даже немного.
Я работаю в междоменном сценарии. Во время входа в систему удаленный сервер возвращает заголовок Set-Cookie, а Access-Control-Allow-Credentials
- true.
Следующий вызов ajax для удаленного сервера должен использовать этот файл cookie.
CORS Access-Control-Allow-Credentials
позволяет выполнять междоменное протоколирование. Для примера рассмотрите https://developer.mozilla.org/En/HTTP_access_control.
Для меня это похоже на ошибку в JQuery (или, по крайней мере, функцию, которая будет в следующей версии).
UPDATE:
Файлы cookie автоматически не устанавливаются из ответа AJAX (ссылка: http://aleembawany.com/2006/11/14/anatomy-of-a-well-designed-ajax-login-experience/)
Почему?
Вы не можете получить значение cookie из ответа, чтобы установить его вручную (http://www.w3.org/TR/XMLHttpRequest/#dom-xmlhttprequest-getresponseheader)
Я запутался..
Должен существовать способ задать jquery.ajax()
параметр XMLHttpRequest.withCredentials = "true"
.
ОТВЕТ:
Вы должны использовать 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
Использование
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 бит "на практике".
Поместите это в свою функцию init:
$.ajaxSetup({
xhrFields: {
withCredentials: true
}
});
Он будет работать.
Уже есть много хороших ответов на этот вопрос, но я подумал, что может быть полезно прояснить случай, когда вы ожидаете, что cookie сеанса будет отправлен, потому что домен cookie совпадает, но он не отправляется, поскольку Запрос AJAX делается для другого субдомена. В этом случае у меня есть файл cookie, который присваивается домену *. Mydomain.com, и я хочу, чтобы он был включен в запрос AJAX для different.mydomain.com ". По умолчанию cookie не отправляется. Вам не нужно отключать HTTPONLY в cookie сеанса, чтобы решить эту проблему. Вам нужно только сделать то, что предложили махровые (fooobar.com/questions/26174/...) и выполните следующие действия.
1) Добавьте в свой запрос ajax следующее.
xhrFields: { withCredentials:true }
2) Добавьте в свои заголовки ответов следующие ресурсы для ресурсов в разных субдоменах.
Access-Control-Allow-Origin : http://original.mydomain.com
Access-Control-Allow-Credentials : true
Попробовав другие решения и все еще не заставив их работать, я выяснил, в чем проблема в моем случае. Я изменил contentType с "application/json" на "text/plain".
$.ajax(fullUrl, {
type: "GET",
contentType: "text/plain",
xhrFields: {
withCredentials: true
},
crossDomain: true
});
У меня была такая же проблема, и некоторые проверки мои script просто не получали cookie sessionid.
Я понял, посмотрев значение cookie sessionid в браузере, которое моя инфраструктура (Django) передавала cookie sessionid с HttpOnly по умолчанию. Это означало, что скрипты не имели доступа к значению sessionid и поэтому не передавали его вместе с запросами. Вид смешного, что HttpOnly будет значением по умолчанию, когда так много вещей использует Ajax, для которого требуется ограничение доступа.
Чтобы исправить это, я изменил настройку (SESSION_COOKIE_HTTPONLY = False), но в других случаях это может быть флаг HttpOnly на пути к файлу cookie
Если вы разрабатываете на localhost
или порт на localhost, например localhost:8080
, в дополнение к шагам, описанным в ответах выше, вам также необходимо убедиться, что вы не передаете значение домена в Set- Заголовок файла cookie.
Вы не можете установить домен в localhost
в заголовке Set-Cookie - это неверно - просто опустите домен.
Смотрите Куки файлы на локальном хосте с явным доменом и Почему asp.net не создает файлы cookie в localhost?
Вы должны инициализировать сеанс перед попыткой входа в систему.
Для php вам нужно сделать
session_start();
на странице с того места, где вы запустите вход в систему ajax.
Итак, SESSIONID
будет создан и сохранен cookie браузера. И отправляется вместе с заголовком запроса во время вызова ajax, если вы выполняете запрос ajax в тот же домен
Для последовательных вызовов ajax браузер будет использовать SESSIONID
, который был создан и сохранен первоначально в cookie браузера, если мы не очистим cookie браузера или не выйдем из системы (или не установим другой файл cookie)
Просто мои 2 цента при установке файла cookie PHPSESSID при работе на локальном хосте и в среде разработчика. Я делаю AJAX-вызов к моей конечной точке REST API на locahost. Скажите, что его адрес mysite.localhost/api/member/login/
(виртуальный хост в моей среде разработки).
Когда я делаю этот запрос на Почтальоне, все идет хорошо, и PHPSESSID устанавливается вместе с ответом.
Когда я запрашиваю эту конечную точку через AJAX со страницы прокси-сервера Browsersync (например, из 122.133.1.110:3000/test/api/login.php
в адресной строке моего браузера, вижу, что домен отличается от mysite.localhost
), PHPSESSID не появляется среди файлов cookie.
Когда я делаю этот запрос прямо со страницы в том же домене (то есть mysite.localhost/test/api/login.php
), PHPSESSID устанавливается просто отлично.
Так что это проблема с файлами cookie для запросов на отправку из разных источников, как указано в ответе @flu выше
Добавление моего сценария и решения на случай, если это поможет кому-то еще. Я сталкивался с подобным случаем при использовании RESTful API. Мой веб-сервер, на котором размещались файлы HTML/Script/CSS и API-интерфейсы сервера приложений, размещался в одном домене. Однако путь был другим.
web server - mydomain/webpages/abc.html
использовал abc.js, который установил cookie с именем mycookie
app server - mydomain/webapis/servicename.
на которые были сделаны вызовы API
Я ожидал файл cookie в mydomain/webapis/servicename и попытался прочитать его, но он не отправлялся. Прочитав комментарий к ответу, я проверил инструмент разработки браузера, который mycookie путь был установлен на "/веб-страницы" и, следовательно, недоступен при вызове службы для
mydomain/webapis/servicename
Поэтому, устанавливая cookie из jquery, я так и сделал -
$.cookie("mycookie","mayvalue",{**path:'/'**});
Возможно, не 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.