2012-03-27 10 views
17

Utilizzo la strategia di Google OpenID Express e Passport e desidero impostare returnURL su ogni richiesta di autorizzazione per poter tornare alla pagina che ha avviato tale autenticazione.Custom returnUrl su Node.js Strategia Google di Passport

La situazione è che ho un'applicazione di diapositive HTML5 con backend Node.js (e con elementi sociali e editor e Portal ed estensioni ... https://github.com/bubersson/humla) e voglio essere in grado di accedere utente su qualche diapositiva (tramite il menu di diapositive ...) ma poi voglio che torni alla stessa slide facilmente.

Quindi mi servirebbe qualcosa del genere?

app.get('/auth/google', function(req,res) { 
    var cust = "http://localhost:1338/"+req.params.xxx; 
    passport.authenticate('google', returnURL:cust, function ... 
} 

Ho letto la guida di Passport, ma ancora non so come farlo. So che questo non sarebbe sicuro, ma come altro potrei farlo?

O come posso rendere l'applicazione per tornare alla pagina da cui è stato avviato il login? O c'è un modo per rendere l'autenticazione OpenID usando AJAX (e comunque essere in grado di usare anche il passaporto)?

risposta

24

ho capito questo per la mia app Twitter autenticazione, sono sicuro che il GoogleStrategy è abbastanza simile. Provare una variante di questo:

Supponendo di aver definito il percorso per la richiamata dal servizio di autenticazione in questo modo (dalla guida passaporto):

app.get('/auth/twitter/callback', 
    passport.authenticate('twitter', { 
     successRedirect: authenticationRedirect(req, '/account') 
    , failureRedirect: '/' 
    }) 
); 

basta cambiare quel blocco a questo:

app.get('/auth/twitter/callback', function(req, res, next){ 
    passport.authenticate('twitter', function(err, user, info){ 
    // This is the default destination upon successful login. 
    var redirectUrl = '/account'; 

    if (err) { return next(err); } 
    if (!user) { return res.redirect('/'); } 

    // If we have previously stored a redirectUrl, use that, 
    // otherwise, use the default. 
    if (req.session.redirectUrl) { 
     redirectUrl = req.session.redirectUrl; 
     req.session.redirectUrl = null; 
    } 
    req.logIn(user, function(err){ 
     if (err) { return next(err); } 
    }); 
    res.redirect(redirectUrl); 
    })(req, res, next); 
}); 

Ora, definire il middleware per percorsi autenticati per memorizzare l'URL originale nella sessione in questo modo:

ensureAuthenticated = function (req, res, next) { 
    if (req.isAuthenticated()) { return next(); } 

    // If the user is not authenticated, then we will start the authentication 
    // process. Before we do, let's store this originally requested URL in the 
    // session so we know where to return the user later. 

    req.session.redirectUrl = req.url; 

    // Resume normal authentication... 

    logger.info('User is not authenticated.'); 
    req.flash("warn", "You must be logged-in to do that."); 
    res.redirect('/'); 
} 

Funziona!

+0

Questo funziona perfettamente, ma al reindirizzamento sembra mancare i parametri hash se l'utente viene inviato via per autenticare e torna indietro. Potrebbe esserci un modo per mantenere quelli nell'URL durante il reindirizzamento dopo l'accesso? http://stackoverflow.com/questions/14124932/passport-js-express-js-forward-user-to-original-destination-after-authenticati – prototype

+0

@ user645715 forse prova a usare 'req.session.redirectUrl = req.originalUrl ; 'invece o 'req.url' –

+0

funziona come un incantesimo, grazie :) – Zub

5

Prova res.redirect('back'); nel callback per passport.authenticate

+0

Ha grazie! Apparentemente la via di ritorno è impostata tra la prima e la seconda richiesta OpenID. Non lo sapevo! Grazie – bubersson

+2

Beh, ho trovato un problema con questo. Funziona solo se ho già effettuato l'accesso utilizzando Google. Se il passaporto reindirizza alla pagina di Google e poi torna al mio sito - la rotta "pagina" è persa. C'è un altro modo per costringerlo a tornare da Google alla mia posizione (la pagina da cui è stato avviato il login)? – bubersson

+0

@bubersson avresti bisogno di usare un approccio più proattivo come quello della prima risposta, per quello, se ho capito bene. – matanster

3

Secondo l'autore questo non è possibile con le strategie OpenID. Siamo riusciti ad aggiornare questi dinamicamente accedendo direttamente alle variabili:

app.get('/auth/google', function(req, res, next) { 
    passport._strategies['google']._relyingParty.returnUrl = 'http://localhost:3000/test'; 
    passport._strategies['google']._relyingParty.realm = 'http://localhost:3000'; 
    passport.authenticate('google')(req, res, next); 
}); 
13

Ovunque avete il vostro pulsante di accesso, aggiungere l'URL corrente della richiesta come un parametro di query (adattiamo per qualsiasi sistema di template si usa):

<a href='/auth/google?redirect=<%= req.url %>'>Log In</a> 

Quindi, aggiungere middleware per la tua GET /auth/google gestore che memorizza questo valore nella req.session:

app.get('/auth/google', function(req, res, next) { 
    req.session.redirect = req.query.redirect; 
    next(); 
}, passport.authenticate('google')); 

Infine, nel tuo gestore di callback, reindirizza all'URL memorizzato nella sessione:

app.get('/auth/google/callback', passport.authenticate('google', 
    failureRedirect: '/' 
), function (req, res) { 
    res.redirect(req.session.redirect || '/'); 
    delete req.session.redirect; 
}); 
+0

E' possibile farlo senza sessioni? – nahtnam

Problemi correlati