Foros del Web » Programando para Internet » Javascript »

persistencia de sesión + cross-origin + ajax

Estas en el tema de persistencia de sesión + cross-origin + ajax en el foro de Javascript en Foros del Web. Buenas. Estoy realizando un proyecto que básicamente se trata de un servicio web RESTful y un conjunto de páginas que mediante AJAX hacen peticiones a ...
  #1 (permalink)  
Antiguo 13/08/2014, 03:31
 
Fecha de Ingreso: julio-2006
Ubicación: Barcelona
Mensajes: 244
Antigüedad: 17 años, 9 meses
Puntos: 32
persistencia de sesión + cross-origin + ajax

Buenas.

Estoy realizando un proyecto que básicamente se trata de un servicio web RESTful y un conjunto de páginas que mediante AJAX hacen peticiones a este servicio. Cuando tomé el proyecto me lo encontré junto, y ahora finalmente me he decidido a separarlo en dos: por una parte el web service y por la otra la página web.

Centrándome en el problema, el api REST tiene estas 3 urls de interés:
Código code:
Ver original
  1. api/login    POST: [usuario, password], Devuelve true/false en función de si el login tiene éxito
  2. api/logged    GET:, Devuelve true/false en función de si está logueado o no.
Y añadí una de test que en producción eliminaré:
Código code:
Ver original
  1. api/login/get/{usuario}/{password}  GET: Hace lo mismo que api/login pero en GET

El web service está en la ruta: http://localhost:55121/
La página web cliente está en: http://localhost:49632/

Así que incluí, de momento, en la cabecera de las respuestas del web service la opción menos restrictiva Access-Control-Allow-Origin:* para permitir peticiones ajax desde la web cliente al web service. Esto me ahorró las quejas del navegador. Sin embargo observo que, ahora que el proyecto está dividido en dos, las variables de sesión no persisten. Cosa que me deja bastante descolocado. Pues, no logro entender la razón y no sé si es algo habitual que ocurra (pero que escapa a mis conocimientos)o se debe a algún error/despiste mío.

Lo del error/despiste, siempre puede ser pero cada vez he aislado más el problema y lo empiezo a dudar pues el comportamiento es el siguiente:

Si hago peticiones ajax desde la aplicación previa a la separación del proyecto en dos partes, funciona correctamente:
Código :
Ver original
  1. 1) api/login        POST(user,1234) -> devuelve true
  2. 2) api/logged        -> devuelve true
  3. 3) api/login/get/user/1234        -> devuelve true
  4. 4) api/logged        -> devuelve true

Una vez separado el proyecto en dos:
Si interactúo desde la web cliente (http://localhost:49632/) haciendo peticiones ajax al web service en este orden:
Código :
Ver original
  1. 1) http://localhost:55121/api/login        POST(user,1234) -> devuelve true
  2. 2) http://localhost:55121/api/logged        -> devuelve false (¡debería devolver true pues está logueado!)
  3. 3) http://localhost:55121/api/login/get/user/1234        -> devuelve true
  4. 4) http://localhost:55121/api/logged        -> devuelve false (¡debería devolver true pues está logueado!)

Si hago peticiones get al mismo web service (http://localhost:55121/):
Código :
Ver original
  1. 1) http://localhost:55121/api/login/get/user/1234        -> devuelve true
  2. 2) http://localhost:55121/api/logged        -> devuelve true (esto me demuestra que el web service separado funciona bien,
  3. el problema debe estar en la interacción entre web cliente y web service).

Comparando las dos maneras de interactuar. Las diferencias que veo es que en la que no funciona interactúo usando ajax y haciendo una petición cross-origin. De ahí deduzco que puede que el problema esté en una de esas dos cosas. Si no va por ahí la cosa ya se me ocurrirá qué otro problema puede ser. Pero de momento dejo la pregunta en el aire a la falta de otras ocurrencias.

Un saludo y gracias!

PD.: Poner esta duda en el foro de javascript está un poco cogido con pinzas. No sabía donde ponerlo. Pero, como aparecía la palabra AJAX y sé que por aquí hay foreros con conocimientos en el mundillo web, me he decantado por ponerlo aquí.
__________________
github.com/xgbuils | npm/xgbuils
  #2 (permalink)  
Antiguo 13/08/2014, 06:12
 
Fecha de Ingreso: julio-2006
Ubicación: Barcelona
Mensajes: 244
Antigüedad: 17 años, 9 meses
Puntos: 32
Respuesta: persistencia de sesión + cross-origin + ajax

Voy a dar un poco de información recogida del network de chrome por si es útil. He hecho las siguientes pruebas:

Antes de hacer cada una de las 3 pruebas he eliminado los cookies. A la información del network de chrome he añadido alguna frase en rojo remarcando diferencias entre las pruebas y escribiendo mis dudas.

1) Proyecto antiguo localhost:14730/ (unido):
peticion via ajax a localhost:14730/api/login/get/user/1234 y después petición ajax a localhost:14730/api/logged

localhost:14730/api/login/get/user/1234
Cita:
Remote Address:::1:14730
Request URL:http://localhost:14730/api/login/get/user/1234
Request Method:GET
Status Code:200 OK
Request Headersview source
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:es-ES,es;q=0.8,en;q=0.6
Connection:keep-alive
Host:localhost:14730
Referer:http://localhost:14730/login
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36
X-Requested-With:XMLHttpRequest ++No está ni en 2 ni en 3
Response Headersview source
--Access-Control-Allow-Origin:* Está en 2 i 3 pero no aquí (normal, no lo necesita)
Cache-Control:no-cache
Content-Length:4
Content-Type:application/json; charset=utf-8
Date:Wed, 13 Aug 2014 11:15:16 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/8.0
Set-Cookie:ASP.NET_SessionId=egw0jjwrllkkbph1az0ovdju; path=/; HttpOnly
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
X-SourceFiles:=?UTF-8?B?QzpcVXNlcnNcZ2FyY2lhYnhcRG9jdW1lbnRzXFZpc3VhbC BTdHVkaW8gMjAxMlxQcm9qZWN0c1xTQ0dcV2ViXFNUQ0cuU0lD LldlYkFwcFxXU0hvbWVcYXBpXGxvZ2luXGdldFxlZ3NcQkFEQU xPTkE=?=
localhost:14730/api/logged
Cita:
Remote Address:::1:14730
Request URL:http://localhost:14730/api/logged
Request Method:GET
Status Code:200 OK
Request Headersview source
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:es-ES,es;q=0.8,en;q=0.6
Connection:keep-alive
Cookie:ASP.NET_SessionId=egw0jjwrllkkbph1az0ovdju
Host:localhost:14730
Referer:http://localhost:14730/login
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36
X-Requested-With:XMLHttpRequest ++No está ni en 2 ni en 3
Response Headersview source
--Access-Control-Allow-Origin:* Está en 2 i 3 pero no aquí (normal, no lo necesita)
Cache-Control:no-cache
Content-Length:4
Content-Type:application/json; charset=utf-8
Date:Wed, 13 Aug 2014 11:15:16 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/8.0
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
X-SourceFiles:=?UTF-8?B?QzpcVXNlcnNcZ2FyY2lhYnhcRG9jdW1lbnRzXFZpc3VhbC BTdHVkaW8gMjAxMlxQcm9qZWN0c1xTQ0dcV2ViXFNUQ0cuU0lD LldlYkFwcFxXU0hvbWVcYXBpXGxvZ2dlZA==?=
2) Proyecto nuevo web service localhost:55121/:
petición via http a localhost:55121/api/login/get/user/1234 y después petición http a localhost:55121/api/logged

localhost:55121/api/login/get/user/1234
Cita:
Remote Address:::1:55121
Request URL:http://localhost:55121/api/login/get/user/1234
Request Method:GET
Status Code:200 OK
Request Headersview source
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 **Diferente a 1 y 3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:es-ES,es;q=0.8,en;q=0.6
Connection:keep-alive
Host:localhost:55121
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36
Response Headersview source
Access-Control-Allow-Origin:*
Cache-Control:no-cache
Content-Length:4
Content-Type:application/json; charset=utf-8
Date:Wed, 13 Aug 2014 11:26:39 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/8.0
Set-Cookie:ASP.NET_SessionId=gmgach1zx121rikyzr3v4osn; path=/; HttpOnly
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
X-SourceFiles:=?UTF-8?B?QzpcVXNlcnNcZ2FyY2lhYnhcRG9jdW1lbnRzXFZpc3VhbC BTdHVkaW8gMjAxMlxQcm9qZWN0c1xTQ0dcV2ViXHByb3ZhbnQz XFNJQy5XZWJBUElcU0lDLldlYkFQSVxhcGlcbG9naW5cZ2V0XG Vnc1xCQURBTE9OQQ==?=
localhost:55121/api/logged
Cita:
Remote Address:::1:55121
Request URL:http://localhost:55121/api/logged
Request Method:GET
Status Code:200 OK
Request Headersview source
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 **Diferente a 1 y 3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:es-ES,es;q=0.8,en;q=0.6
Connection:keep-alive
Cookie:ASP.NET_SessionId=gmgach1zx121rikyzr3v4osn
Host:localhost:55121
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36
Response Headersview source
Access-Control-Allow-Origin:*
Cache-Control:no-cache
Content-Length:4
Content-Type:application/json; charset=utf-8
Date:Wed, 13 Aug 2014 11:28:24 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/8.0
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
X-SourceFiles:=?UTF-8?B?QzpcVXNlcnNcZ2FyY2lhYnhcRG9jdW1lbnRzXFZpc3VhbC BTdHVkaW8gMjAxMlxQcm9qZWN0c1xTQ0dcV2ViXHByb3ZhbnQz XFNJQy5XZWJBUElcU0lDLldlYkFQSVxhcGlcbG9nZ2Vk?=
3) Proyecto nuevo página web localhost:49632/:
petición via ajax a localhost:55121/api/login/get/user/1234 y después petición ajax a localhost:55121/api/logged

localhost:55121/api/login/get/user/1234
Cita:
Remote Address:::1:55121
Request URL:http://localhost:55121/api/login/get/user/1234
Request Method:GET
Status Code:200 OK
Request Headersview source
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:es-ES,es;q=0.8,en;q=0.6
Connection:keep-alive
Host:localhost:55121
Origin:http://localhost:49632
Referer:http://localhost:49632/login
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36
Response Headersview source
Access-Control-Allow-Origin:*
Cache-Control:no-cache
Content-Length:4
Content-Type:application/json; charset=utf-8
Date:Wed, 13 Aug 2014 11:30:40 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/8.0
Set-Cookie:ASP.NET_SessionId=xdbot45jhb4u1ykhuswrmx5i; path=/; HttpOnly
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
X-SourceFiles:=?UTF-8?B?QzpcVXNlcnNcZ2FyY2lhYnhcRG9jdW1lbnRzXFZpc3VhbC BTdHVkaW8gMjAxMlxQcm9qZWN0c1xTQ0dcV2ViXHByb3ZhbnQz XFNJQy5XZWJBUElcU0lDLldlYkFQSVxhcGlcbG9naW5cZ2V0XG Vnc1xCQURBTE9OQQ==?=
localhost:55121/api/logged
Cita:
Remote Address:::1:55121
Request URL:http://localhost:55121/api/logged
Request Method:GET
Status Code:200 OK
Request Headersview source
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:es-ES,es;q=0.8,en;q=0.6
Connection:keep-alive
--Falta el cookie de sesión que sí que está en 1 y 2. Por eso devuelve false. ¿Pero por que no hay cookie?
Host:localhost:55121
Origin:http://localhost:49632
Referer:http://localhost:49632/login
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36
Response Headersview source
Access-Control-Allow-Origin:*
Cache-Control:no-cache
Content-Length:5 **Diferente a 1 y 2 (normal, pues la respuesta es "false" que tiene 5 caracteres. ¿Pero por qué es false?
Content-Type:application/json; charset=utf-8
Date:Wed, 13 Aug 2014 11:30:40 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/8.0
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
X-SourceFiles:=?UTF-8?B?QzpcVXNlcnNcZ2FyY2lhYnhcRG9jdW1lbnRzXFZpc3VhbC BTdHVkaW8gMjAxMlxQcm9qZWN0c1xTQ0dcV2ViXHByb3ZhbnQz XFNJQy5XZWJBUElcU0lDLldlYkFQSVxhcGlcbG9nZ2Vk?=
Me da mala espina esta sentencia:
Set-Cookie:ASP.NET_SessionId=xdbot45jhb4u1ykhuswrmx5i; path=/; HttpOnly
Aunque la sentencia es igual para todas las pruebas, tengo entendido que esta restricción impide que las cookies funcionen via script. Eso me daría a entender porque la prueba 2 funciona y la prueba 3 no. Sin embargo, si fuera por eso, ¿por qué funciona la prueba 1 si se están haciendo las peticiones via ajax?

A ver si alguien sabría aclarármelo.

Muchas gracias!
__________________
github.com/xgbuils | npm/xgbuils
  #3 (permalink)  
Antiguo 13/08/2014, 16:59
Avatar de zerokilled
Javascripter
 
Fecha de Ingreso: abril-2009
Ubicación: Isla del Encanto, La Borinqueña [+>==]
Mensajes: 8.050
Antigüedad: 15 años
Puntos: 1485
Respuesta: persistencia de sesión + cross-origin + ajax

buenas,
no creo que sea por ahi que falle la persistencia de la session. httponly solamente indica que la cookie se puede modificar mediante protocolo http. en el primer caso es exitoso porque es el server quien declara la cookie mediante el response http. tampoco veo que la cookie se defina con un tiempo de expiracion (expires o max-age). por lo que la cookie se mantiene mientra la seccion del navegador permanezca abierta. o sea, mientras no cierres el navegador. lo que si veo es que las cookies no estan siendo transferible entre ambos servidores. quizas tengas que definir un dominio para extender la visibilidad de la cookie entre servidores. o sea, el header domain de la coookie. aun asi tengo duda si te funcione, porque estas trabajando en el localhost con diferentes puertos; no se si eso tenga algo que ver.
__________________
la maldad es una virtud humana,
y la espiritualidad es la lucha del hombre contra su maldad.
  #4 (permalink)  
Antiguo 14/08/2014, 00:31
 
Fecha de Ingreso: julio-2006
Ubicación: Barcelona
Mensajes: 244
Antigüedad: 17 años, 9 meses
Puntos: 32
Respuesta: persistencia de sesión + cross-origin + ajax

Gracias zerokilled por la ayuda. Así que HttpOnly lo único que hace es impedir que el cookie pueda ser modificado mediante javascript pero éste se envia igual. Estaba confundido con esto.

Por otro lado, acabo de solucionarlo. La solución estaba en otro post que abrí hace un tiempo en este mismo subforo. Se trata del uso de Access-Control-Allow-Credentials. La otra vez que me lo explicaron, como no estaba usando cookies, no vi para que servía esta directiva y no le di la importancia que tenia. He encontrado una explicación en este enlace(Apartado "Credenciales y autenticación") que me ha dado las pistas necesarias para que me funcione.

Sin embargo no he acabado de entender el concepto. Por ejemplo se dice refiriendose a la opcion de configuración withCredentials cuando haces una petición ajax mediante jQuery:
Cita:
La marca withCredentials hace dos cosas: Si el servidor emite una cookie, el explorador puede aceptarla; si el explorador tiene una cookie, puede enviarla al servidor.
Esto es justamente lo que necesito, que pueda recibir una cookie del servidor y también poder enviarla. Pero no me ha hecho falta poner esa opción para que la cookie llegara. Luego dice para que sirve Access-Control-Allow-Credentials:
Cita:
El encabezado de respuesta Access-Control-Allow-Credentials hace dos cosas: si la respuesta tiene una cookie, el explorador puede aceptarla; y si el explorador envió una cookie con la solicitud, el cliente JavaScript puede recibir los resultados de la llamada.
Entonces, ¿poner esta cabecera a true no es lo mismo que lo de arriba? Yo he puesto Access-Control-Allow-Credentials a true y me ha funcionado sin tener que retocar la petición ajax.
Luego acaba diciendo:
Cita:
En otras palabras, si el cliente establece withCredentials, entonces el cliente solo recibirá una devolución de llamada con el acierto en JavaScript si el servidor permite credenciales (en la respuesta). Si se hubiera establecido withCredentials y el servidor no permitiera las credenciales, entonces el cliente no obtendría acceso a los resultados y se invocaría la devolución de llamada de error de cliente.
Es decir, si pones withCredentials pero el servidor no tiene Access-Control-Allow-Credentials: true entonces no funcionará. ¿Pero y en caso inverso? ¿si pones Access-Control-Allow-Credentials: true pero la petición ajax no tiene withCredentials: true que ocurrirá? Como he dicho, sin poner withCredentials a mi me funciona igualmente. Entonces no acabo de entender para qué sirve withCredentials.

Un saludo y gracias nuevamente. Ahora al menos ya puedo ir apañándome.
__________________
github.com/xgbuils | npm/xgbuils
  #5 (permalink)  
Antiguo 14/08/2014, 01:27
 
Fecha de Ingreso: julio-2006
Ubicación: Barcelona
Mensajes: 244
Antigüedad: 17 años, 9 meses
Puntos: 32
Respuesta: persistencia de sesión + cross-origin + ajax

Retiro lo dicho sobre withCredentials. Escribir a horas tan tempranas no es bueno. Tuve el lapsus de probar con el proyecto antiguo que tenía el web service y la web juntos. Con el proyecto separado es necesario withCredentials a true.

Aquí más información: http://www.html5rocks.com/en/tutorials/cors/

Un saludo!
__________________
github.com/xgbuils | npm/xgbuils

Etiquetas: ajax, session
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 07:36.