Angularjs $ http no parece entender “Set-Cookie” en la respuesta

Tengo un nodejs express REST api con módulo Passport para autenticación. Un método de inicio de sesión (GET) devuelve una cookie en el encabezado. Cuando lo llamo desde Chrome, funciona bien, mi cookie está configurada en mi navegador.

Pero si lo llamo a través de $ http desde Angularjs, la cookie no está configurada.

Set-Cookie:connect.sid=s%3Ad7cZf3DSnz-IbLA_eNjQr-YR.R%2FytSJyd9cEhX%2BTBkmAQ6WFcEHAuPJjdXk3oq3YyFfI; Path=/; HttpOnly 

Como puede ver arriba, Set-Cookie está presente en el encabezado de la respuesta del servicio http.

Quizás HttpOnly puede ser la fuente de este problema? Si es así, ¿cómo puedo cambiarlo? Aquí está mi configuración expresa:

 app.configure(function () { app.use(allowCrossDomain); app.use(express.bodyParser()); app.use(express.cookieParser()) app.use(express.session({ secret: 'this is a secret' })); app.use(flash()); //passport init app.use(passport.initialize()); app.use(passport.session()); app.set('port', process.env.PORT || 8080); }); 

Gracias por tu ayuda

Asegúrese de configurar su solicitud de $ http para usar credenciales. De la documentación de XHR:

https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS

La capacidad más interesante expuesta tanto por XMLHttpRequest como por Access Control es la capacidad de realizar solicitudes “con credenciales” que tengan en cuenta las cookies HTTP y la información de autenticación HTTP. De forma predeterminada, en las invocaciones XMLHttpRequest entre sitios, los navegadores no enviarán credenciales. Se debe establecer un indicador específico en el objeto XMLHttpRequest cuando se invoca.

Puede usar el objeto de opciones para configurar el uso de credenciales, vea

http://docs.angularjs.org/api/ng.$http

Ejemplo:

 $http({withCredentials: true, ...}).get(...) 

¿Cómo está verificando la existencia de la cookie?

$http es solo una envoltura alrededor del XHR del navegador, al igual que $.ajax y amigos de jQuery. Eso significa que su navegador manejará las cookies normalmente.

Supongo que la cookie se está configurando, pero estás tratando de leerla a través de document.cookie . HttpOnly evita que el script tenga acceso a la cookie. Ésto es una cosa buena.

HttpOnly ayuda a mitigar los ataques XSS. Impide que una secuencia de comandos malintencionada robe la ficha de sesión de un usuario (y, por lo tanto, su inicio de sesión). No HttpOnly .

No deberías necesitar la cookie de todos modos. Como $http es solo una envoltura de XHR, el navegador enviará automáticamente la cookie la próxima vez que realice una solicitud. Puede verificar esto mirando las solicitudes en el panel de red de Herramientas para desarrolladores.

{withCredential : true} el problema estableciendo {withCredential : true} en la solicitud $http angular y estableciendo:

 res.header("Access-Control-Allow-Credentials", true); 

en mi configuración de servidor express. Al hacer esto, mi cookie aparece bien en la lista de cookies de mi navegador.

Puede cambiarlo configurando express.session :

 app.use(express.session({ secret : 'this is a secret', cookie : { httpOnly : false, maxAge : XXX // see text } }); 

Pero no creo que Angular se preocupe demasiado por las cookies, esas son manejadas por el navegador (y estoy de acuerdo con @ josh3736 en que debería mantener httpOnly como true ).

Puede tener algo que ver con que sus cookies sean cookies de sesión (navegador). Puede probar y ver si funciona mejor al establecer explícitamente un maxAge para la cookie (en milisegundos).