Crie uma API oauth segura com passport.js e express.js (node.js)

Eu acho que tenho um problema específico, a menos que eu não esteja fazendo as coisas da maneira certa.

Eu tenho um aplicativo com 2 lados, um cliente (site html) e uma API (construída com express + mongodb). A API precisará ser acessada com segurança. Ambos estão em domínios diferentes, por enquanto, digamos que meu site esteja em domain.com e minha API esteja em api.com:3000.

Eu adicionei o passaporte para obter um token de acesso do Github, pois estou criando meus usuários com os dados deles, para que eu possa ter um "Fazer login com o Github" basicamente.

Meu processo atual é:

1) o cliente (o site), abre um pop-up na API

window.open("http://api.com:3000/oauth")

2) O servidor expresso, inicie o processo de passaporte:

app.get('/oauth', passport.authenticate('github'), function(req, res) {

});

Para a estratégia, useieste código.

3) eu redirecionar o retorno de chamada para uma url que fecha o pop-up (javascript com um window.close ()):

app.get('/oauth/callback', passport.authenticate('github', { failureRedirect: '/' }), function(req, res) {
    res.redirect('/auth_close');
});

Nesse ponto, tudo está bem, agora estou logado na API. Meu problema é como devolver os dados ao cliente, pois o cliente ainda não sabe nada sobre accessToken, usuário ou id do usuário.

Então, do cliente (o site que abre o popup), eu tentei abordagens diferentes:

Obtendo um valor a partir do pop-up: não funciona por causa do redirecionamento, eu perco o controle da informação pop-up de javascript

chamando minha API para obter o "usuário atual" na sessão, comohttp://api.com:3000/current Mais um pedido, não ideal, mas este é um trabalho. No entanto, ainda tenho um problema.

Este / url atual está retornando o usuário se eu chegar a partir do navegador, porque o navegador envia no pedido de cabeçalho o cookie de sessão expressa:

Cookie:connect.sid=s%3AmDrM5MRA34UuNZqiL%2BV7TMv6.Paw6O%2BtnxQRo0vYNKrher026CIAnNsHn4OJdptb8KqE

O problema é que eu preciso fazer esse pedido de jquery ou similar, e é aí que ele falha porque a sessão não é enviada. Então o usuário não é retornado:

app.get('/current', function() {
    // PROBLEM HERE, req.user is undefined with ajax calls because of the session!
});

Eu encontrei uma maneira de fazê-lo funcionar, mas eu não estou feliz com porque eu vou ter problemas de CORS cross-navegadores, é adicionar para expressar:

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

E adicione o campo withCredentials em uma chamada jquery ajax, conforme explicadoAqui.

Um mapa de fieldName-fieldValue pares para definir no objeto XHR nativo. Por exemplo, você pode usá-lo para definir withCredentials como true para solicitações entre domínios, se necessário.

$.ajax({
   url: a_cross_domain_url,
   xhrFields: {
      withCredentials: true
   }
});

Eu também não estou feliz com isso, pois estou perdendo o curinga no meu cabeçalho:Access-Control-Allow-Origin, Preciso especificar um domínio, conforme explicadoAqui.

Então, eu não tenho certeza da abordagem que devo tomar aqui, a única coisa que eu preciso é que o cliente obtenha um accessToken ou um ID de usuário de volta do processo oauth de passaporte. A ideia é usar esse token em cada chamada para a API para validar as chamadas.

Qualquer pista?

questionAnswers(2)

yourAnswerToTheQuestion