success - ¿Por qué el método.ajax() de jquery no está enviando mi cookie de sesión?
set cookie ajax request (11)
Después de iniciar sesión a través de $.ajax()
en un sitio, estoy intentando enviar una segunda solicitud de $.ajax()
a ese sitio, pero cuando verifico los encabezados enviados mediante FireBug, no se incluye ninguna cookie de sesión en la solicitud. .
¿Qué estoy haciendo mal?
Debe iniciar la sesión antes de intentar iniciar sesión.
Para php, tienes que hacer
session_start();
en la página desde donde inicia la sesión de inicio de sesión ajax.
Para que el SESSIONID
se cree y almacene la cookie del navegador. Y se envía junto con el encabezado de solicitud durante la llamada ajax, si realiza la solicitud ajax para el mismo dominio
Para las sucesivas llamadas ajax, el navegador utilizará el SESSIONID
que se creó y almacenó inicialmente en la cookie del navegador, a menos que SESSIONID
la cookie del navegador o cerremos la sesión (o configuremos otra cookie)
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 secuencia de comandos simplemente no conseguía la cookie de sessionid.
Me di cuenta, mirando el valor de cookie de sessionid en el navegador, 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 un poco ridículo que HttpOnly sea el valor predeterminado cuando tantas cosas usan Ajax, lo que requeriría una restricción de acceso.
Para solucionar este problema cambié una configuración (SESSION_COOKIE_HTTPONLY = False) pero en otros casos puede ser un indicador "HttpOnly" en la ruta de 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
establecidas en true.
La próxima llamada ajax al servidor remoto debe usar esta cookie.
Las Access-Control-Allow-Credentials
de Access-Control-Allow-Credentials
están ahí para permitir el registro de dominios cruzados. Consulte https://developer.mozilla.org/En/HTTP_access_control para ver ejemplos.
Para mí, parece un error en JQuery (o, al menos, una 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 configurarlo manualmente ( http://www.w3.org/TR/XMLHttpRequest/#dom-xmlhttprequest-getresponseheader )
Estoy confundido..
Debe existir una forma de pedir a
jquery.ajax()
que establezca el parámetroXMLHttpRequest.withCredentials = "true"
.
RESPUESTA: Debes usar el xhrFields
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í grandes 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 no se devolverá al script. Consulte: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials
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.
Quizás intentó llamar a una url desde www.domain-a.com
mientras su script de llamada estaba en www.domain-b.com
(En otras palabras: realizó una llamada entre varios dominios, en cuyo caso el navegador no enviará ninguna cookie). para proteger su privacidad).
En este caso sus opciones son:
- Escriba un pequeño proxy que resida en el dominio-b y reenvíe sus solicitudes al dominio-a. Su navegador le permitirá llamar al proxy porque está en el mismo servidor que el script de llamada.
Luego, usted puede configurar este proxy para que acepte un nombre de cookie y un parámetro de valor que puede enviar al dominio-a. Pero para que esto funcione, necesita saber el nombre de la cocinera y valorar su servidor en el dominio, que necesita autenticación. - Si está recuperando objetos JSON, intente utilizar una solicitud JSONP lugar. jQuery apoya estos. Pero debe modificar su servicio en el dominio-a para que devuelva las respuestas JSONP válidas.
Me alegro si eso ayudó incluso un poco.
Ponga esto en su función de inicio:
$.ajaxSetup({
xhrFields: {
withCredentials: true
}
});
Funcionará.
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 que no está pasando un valor de dominio en el encabezado Set-Cookie.
No puede establecer el dominio en localhost
en el encabezado Set-Cookie, eso es incorrecto, simplemente omita el dominio.
Consulte 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 la cookie PHPSESSID cuando se encuentra en localhost y en un entorno dev. Realizo la llamada AJAX a mi extremo REST API en el locahost. 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 de proxy de Browsersync (por ejemplo, desde
122.133.1.110:3000/test/api/login.php
en la línea de dirección de mi navegador, vea que el dominio es diferente versusmysite.localhost
) PHPSESSID no aparece entre las cookies .Cuando hago esta solicitud directamente desde la página en el mismo dominio (es decir,
mysite.localhost/test/api/login.php
), PHPSESSID se configura bien.
Así que este es un problema de solicitud de origen cruzado de cookies, como se menciona en @flu respuesta arriba
Tal vez no esté al 100% respondiendo a la pregunta, pero me topé con este hilo con la esperanza de resolver un problema de sesión cuando ajax publicaba un archivo subido desde el administrador de recursos del innovastudio editor. Eventualmente la solución fue simple: tienen un flash-uploader. Deshabilitando eso
var flashUpload = false;
en asset.php) y las luces empezaron a parpadear de nuevo.
Como estos problemas pueden ser muy difíciles de depurar, descubrí que poner algo como lo siguiente en el controlador de carga lo pondrá a usted (bueno, a mí en este caso) 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");
Una inmersión en el registro y rápidamente vi la sesión faltante, donde no se envió ninguna cookie.
Utilizando
xhrFields: { withCredentials:true }
como parte de mi llamada jQuery ajax era solo parte de la solución. También necesitaba que me devolvieran los encabezados en la respuesta de OPCIONES 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 OPCIONES y no "*". Logré esto leyendo el origen de la solicitud y rellenándolo de nuevo en la respuesta, probablemente evadiendo el motivo 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! http://www.w3.org/TR/cors/#access-control-allow-origin-response-header NB el bit "en la práctica".
Ya hay muchas respuestas buenas a esta pregunta, pero pensé que podría ser útil aclarar el caso en el que se espera que se envíe la cookie de sesión porque el dominio de la cookie coincide, pero no se está enviando porque la solicitud AJAX es siendo hecho a un subdominio diferente. En este caso, tengo una cookie asignada al dominio * .mydomain.com y deseo que se incluya en una solicitud de AJAX a different.mydomain.com ". De forma predeterminada, 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 se sugiere ( https://.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