Eu tenho uma API REST de nodejs express com o módulo Passport para autenticação. Um método de login (GET) retorna um cookie no header. Quando eu o chamo do Chrome ele funciona bem, meu cookie é definido no meu navegador.
Mas se eu chamá-lo através de $ http do Angularjs, o cookie não está definido.
Set-Cookie:connect.sid=s%3Ad7cZf3DSnz-IbLA_eNjQr-YR.R%2FytSJyd9cEhX%2BTBkmAQ6WFcEHAuPJjdXk3oq3YyFfI; Path=/; HttpOnly
Como você pode ver acima, o Set-Cookie está presente no header da resposta do serviço http.
Talvez o HttpOnly possa ser a fonte desse problema? Se sim, como posso mudar isso? Aqui está minha configuração expressa:
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); });
obrigado pela ajuda
Certifique-se de configurar sua solicitação $ http para usar credenciais. Da documentação do XHR:
https://developer.mozilla.org/pt-BR/docs/HTTP/Access_control_CORS
O recurso mais interessante exposto tanto pelo XMLHttpRequest quanto pelo Access Control é a capacidade de fazer solicitações “credenciadas” que tenham conhecimento de cookies HTTP e informações de autenticação HTTP. Por padrão, nas chamadas XMLHttpRequest entre sites, os navegadores não enviam credenciais. Um sinalizador específico deve ser definido no object XMLHttpRequest quando ele é invocado.
Você pode usar o object options para definir o uso de credenciais, consulte
http://docs.angularjs.org/api/ng.$http
Exemplo:
$http({withCredentials: true, ...}).get(...)
Como você está verificando a existência do cookie?
$http
é apenas um invólucro em torno do XHR do navegador, assim como o $.ajax
e os amigos do jQuery. Isso significa que seu navegador manipulará os cookies normalmente.
Meu palpite é que o cookie está sendo definido, mas você está tentando lê-lo através do document.cookie
. HttpOnly
impede que o script tenha access ao cookie. Isto é uma coisa boa.
HttpOnly
ajuda a mitigar contra ataques XSS. Isso torna impossível que um script mal-intencionado roube o token de session de um usuário (e, portanto, seu login). Não desligue o HttpOnly
.
Você não deve precisar do cookie de qualquer maneira. Como $http
é apenas um wrapper em torno do XHR, o navegador enviará automaticamente o cookie na próxima vez que você fizer uma solicitação. Você pode verificar isso observando as solicitações no painel de Rede das Ferramentas do Desenvolvedor.
Eu resolvi o problema definindo {withCredential : true}
no pedido $http
angular e definindo:
res.header("Access-Control-Allow-Credentials", true);
na minha configuração do servidor expresso. Ao fazer isso, meu cookie aparece bem na minha lista de cookies do navegador.
Você pode alterá-lo configurando express.session
:
app.use(express.session({ secret : 'this is a secret', cookie : { httpOnly : false, maxAge : XXX // see text } });
Mas eu não acho que o Angular se preocupa muito com cookies, esses são manipulados pelo navegador (e eu concordo com o @josh3736 que você deve manter o httpOnly
como true
).
Pode ter algo a ver com seus cookies sendo cookies de session (navegador). Você pode tentar e ver se funciona melhor definindo explicitamente um maxAge
para o cookie (em milissegundos).