Después de iniciar sesión en $.ajax()
un sitio, intento enviar una segunda $.ajax()
solicitud a ese sitio, pero cuando verifico los encabezados enviados con FireBug, no se incluye ninguna cookie de sesión en la solicitud.
¿Qué estoy haciendo mal?
Después de iniciar sesión en $.ajax()
un sitio, intento enviar una segunda $.ajax()
solicitud a ese sitio, pero cuando verifico los encabezados enviados con FireBug, no se incluye ninguna cookie de sesión en la solicitud.
¿Qué estoy haciendo mal?
Respuestas:
Las llamadas AJAX solo envían cookies si la url a la que llama está en el mismo dominio que su script de llamada.
Esto puede ser un problema de dominio cruzado.
Tal vez trató de llamar a una URL desde www.domain-a.com
que su script de llamada estaba activado www.domain-b.com
(en otras palabras: realizó una llamada entre dominios, en cuyo caso el navegador no enviará ninguna cookie para proteger su privacidad).
En este caso, sus opciones son:
Me alegro si eso ayudó incluso un poco.
path=/something
y está solicitando la página/another
, la cookie no se enviará. Cuando solicite la página, /something
la cookie se enviará como se esperaba. Así que verifique también el código que establece la cookie.
Estoy operando en un escenario de dominio cruzado. Durante el inicio de sesión, el servidor remoto devuelve el encabezado Set-Cookie junto con Access-Control-Allow-Credentials
set a true.
La próxima llamada ajax al servidor remoto debe usar esta cookie.
CORS Access-Control-Allow-Credentials
está ahí para permitir el registro entre dominios. Consulte https://developer.mozilla.org/En/HTTP_access_control para ver ejemplos.
Para mí, parece un error en JQuery (o al menos característica en la próxima versión).
ACTUALIZAR:
Las cookies no se configuran automáticamente a partir de la respuesta AJAX (cita: http://aleembawany.com/2006/11/14/anatomy-of-a-well-designed-ajax-login-experience/ )
¿Por qué?
No puede obtener el valor de la cookie de la respuesta para configurarla manualmente ( http://www.w3.org/TR/XMLHttpRequest/#dom-xmlhttprequest-getresponseheader )
Estoy confundido..
Debería existir una manera de pedir jquery.ajax()
establecer el XMLHttpRequest.withCredentials = "true"
parámetro.
RESPUESTA:
Debes usar el xhrFields
parámetro de http://api.jquery.com/jQuery.ajax/
El ejemplo en la documentación es:
$.ajax({
url: a_cross_domain_url,
xhrFields: {
withCredentials: true
}
});
También es importante que el servidor responda correctamente a esta solicitud. Copiando aquí excelentes comentarios de @ Frédéric y @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: *
Entonces, cuando la solicitud es:
Origin: http://foo.example
Cookie: pageAccess=2
El servidor debe responder con:
Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Credentials: true
[payload]
De lo contrario, la carga útil no se devolverá al script. Ver: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials
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: *
developer.mozilla.org/en-US/docs/Web/HTTP/…
Utilizando
xhrFields: { withCredentials:true }
Como parte de mi llamada jQuery ajax fue solo parte de la solución. También necesitaba que me devolvieran los encabezados en la respuesta OPTIONS de mi recurso:
Access-Control-Allow-Origin : http://www.wombling.com
Access-Control-Allow-Credentials : true
Era importante que solo un "origen" permitido estuviera en el encabezado de respuesta de la llamada OPTIONS y no "*". Lo logré leyendo el origen de la solicitud y llenándolo nuevamente a la respuesta, probablemente eludiendo la razón original de la restricción, pero en mi caso de uso la seguridad no es primordial.
Pensé que valía la pena mencionar explícitamente el requisito de un solo origen, ya que el estándar W3C permite una lista separada por espacios, ¡pero Chrome no lo hace! http://www.w3.org/TR/cors/#access-control-allow-origin-response-header NB el bit "en la práctica".
Pon esto en tu función init:
$.ajaxSetup({
xhrFields: {
withCredentials: true
}
});
Funcionará.
Ya hay muchas buenas respuestas a esta pregunta, pero pensé que podría ser útil aclarar el caso en el que esperaría que se envíe la cookie de sesión porque el dominio de la cookie coincide, pero no se envía porque la solicitud AJAX es siendo hecho a un subdominio diferente. En este caso, tengo una cookie que está asignada al dominio * .midominio.com , y deseo que se incluya en una solicitud AJAX a different.mydomain.com ". Por defecto, la cookie no se envía. No necesita deshabilitar HTTPONLY en la cookie de sesión para resolver este problema. Solo necesita hacer lo que sugiere wombling ( https://stackoverflow.com/a/23660618/545223 ) y hacer lo siguiente.
1) Agregue lo siguiente a su solicitud de ajax.
xhrFields: { withCredentials:true }
2) Agregue lo siguiente a sus encabezados de respuesta para los recursos en los diferentes subdominios.
Access-Control-Allow-Origin : http://original.mydomain.com
Access-Control-Allow-Credentials : true
Después de probar las otras soluciones y aún no lograr que funcionara, descubrí cuál era el problema en mi caso. Cambié contentType de "application / json" a "text / plain".
$.ajax(fullUrl, {
type: "GET",
contentType: "text/plain",
xhrFields: {
withCredentials: true
},
crossDomain: true
});
Estaba teniendo el mismo problema y haciendo algunas comprobaciones mi script simplemente no estaba recibiendo la cookie sessionid.
Al observar el valor de la cookie de sessionid en el navegador, descubrí que mi framework (Django) estaba pasando la cookie de sessionid con HttpOnly como predeterminado. Esto significaba que los scripts no tenían acceso al valor de sessionid y, por lo tanto, no lo pasaban junto con las solicitudes. Es ridículo que HttpOnly sea el valor predeterminado cuando tantas cosas usan Ajax que requerirían restricción de acceso.
Para solucionar esto, cambié una configuración (SESSION_COOKIE_HTTPONLY = False) pero en otros casos puede ser un indicador "HttpOnly" en la ruta de la cookie
Si está desarrollando en localhost
o un puerto en localhost como localhost:8080
, además de los pasos descritos en las respuestas anteriores, también debe asegurarse de no pasar un valor de dominio en el encabezado Set-Cookie.
No puede establecer el dominio localhost
en el encabezado Set-Cookie, eso es incorrecto, solo omita el dominio.
Vea Cookies en localhost con dominio explícito y ¿Por qué asp.net no crea cookies en localhost?
Solo mis 2 centavos para configurar el problema de cookies PHPSESSID cuando estoy en localhost y en un entorno de desarrollo. Realizo la llamada AJAX a mi punto final API REST en el host local. Digamos que su dirección es mysite.localhost/api/member/login/
(host virtual en mi entorno de desarrollo).
Cuando hago esta solicitud en Postman , las cosas van bien y PHPSESSID se configura con la respuesta.
Cuando solicito este punto final a través de AJAX desde la página proxy de Browsersync (por ejemplo, 122.133.1.110:3000/test/api/login.php
en la línea de dirección de mi navegador, veo que el dominio es diferente vs mysite.localhost
) PHPSESSID no aparece entre las cookies.
Cuando realizo esta solicitud directamente desde la página en el mismo dominio (es decir mysite.localhost/test/api/login.php
), PHPSESSID está configurado correctamente.
Entonces, este es un problema de cookies de solicitud de origen de origen cruzado como se menciona en la respuesta @flu anterior
Agregar mi escenario y solución en caso de que ayude a alguien más. Encontré un caso similar al usar API RESTful. Mi servidor web que alojaba archivos HTML / Script / CSS y el servidor de aplicaciones que exponía API estaban alojados en el mismo dominio. Sin embargo, el camino era diferente.
servidor web: midominio / páginas web /abc.html
utiliza abc.js que establece la cookie llamada mycookie
servidor de aplicaciones: midominio / webapis / servicename.
a lo que se hicieron llamadas API
Esperaba la cookie en mydomain / webapis / servicename e intenté leerla pero no se estaba enviando. Después de leer el comentario de la respuesta, verifiqué en la herramienta de desarrollo del navegador que la ruta de mycookie estaba configurada en "/ páginas web " y, por lo tanto, no estaba disponible en la llamada de servicio para
midominio / webapis / servicename
Entonces, al configurar la cookie desde jquery, esto es lo que hice:
$.cookie("mycookie","mayvalue",{**path:'/'**});
Tal vez no responda al 100% a la pregunta, pero me topé con este hilo con la esperanza de resolver un problema de sesión cuando publico una carga de archivo desde el administrador de activos del editor innovastudio. Finalmente, la solución fue simple: tienen un cargador de flash. Deshabilitar eso (configuración
var flashUpload = false;
en asset.php) y las luces comenzaron a parpadear nuevamente.
Como estos problemas pueden ser muy difíciles de depurar, descubrí que poner algo como lo siguiente en el controlador de carga lo colocará (en este caso, a mí) en el camino correcto:
$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");
Me sumergí en el registro y rápidamente vi la sesión perdida, donde no se envió ninguna cookie.
session_name(isset($_GET['sess']) ? $_GET['sess'] : null);session_start();
esta manera, obtendrían algo que funciona