Cosa fa il middleware passport.session ()?


125

Sto costruendo un sistema di autenticazione utilizzando Passport.js utilizzando Easy Node Authentication: Setup and Local tutorial .

Sono confuso su cosa passport.session()fa.

Dopo aver giocato con i diversi middleware sono arrivato a capire che express.session()è ciò che invia un ID di sessione tramite i cookie al client, ma sono confuso su cosa passport.session()fa e perché è necessario oltre a express.session().

Ecco come imposto la mia applicazione:

// Server.js configura l'applicazione e imposta il server web

//importing our modules
var express = require('express');
var app = express();
var port = process.env.PORT || 8080;
var mongoose = require('mongoose');
var passport = require('passport');
var flash = require('connect-flash');

var configDB = require('./config/database.js');

//Configuration of Databse and App

mongoose.connect(configDB.url); //connect to our database

require('./config/passport')(passport); //pass passport for configuration

app.configure(function() {

    //set up our express application

    app.use(express.logger('dev')); //log every request to the console
    app.use(express.cookieParser()); //read cookies (needed for auth)
    app.use(express.bodyParser()); //get info from html forms

    app.set('view engine', 'ejs'); //set up ejs for templating

    //configuration for passport
    app.use(express.session({ secret: 'olhosvermelhoseasenhaclassica', maxAge:null })); //session secret
    app.use(passport.initialize());
    app.use(passport.session()); //persistent login session
    app.use(flash()); //use connect-flash for flash messages stored in session

});

//Set up routes
require('./app/routes.js')(app, passport);

//launch
app.listen(port);
console.log("Server listening on port" + port);

Risposte:


139

passport.session() funge da middleware per alterare l'oggetto req e modificare il valore "utente" che è attualmente l'id di sessione (dal cookie del client) nel vero oggetto utente deserializzato.

Sebbene le altre risposte esprimano alcuni punti positivi, ho pensato che potessero essere forniti alcuni dettagli più specifici.

app.use(passport.session());

è equivalente a

app.use(passport.authenticate('session'));

Dove "sessione" si riferisce alla seguente strategia fornita in bundle con passportJS.

https://github.com/jaredhanson/passport/blob/master/lib/strategies/session.js

Nello specifico righe 59-60:

var property = req._passport.instance._userProperty || 'user';
req[property] = user;

Dove essenzialmente funge da middleware e altera il valore della proprietà 'user' nell'oggetto req per contenere l'identità deserializzata dell'utente. Per consentire che funzioni correttamente, è necessario includere serializeUsere deserializeUserfunctions nel codice personalizzato.

passport.serializeUser(function (user, done) {
    done(null, user.id);
});

passport.deserializeUser(function (user, done) {
    //If using Mongoose with MongoDB; if other you will need JS specific to that schema.
    User.findById(user.id, function (err, user) {
        done(err, user);
    });
});

Questo troverà l'utente corretto dal database e lo passerà come variabile di chiusura nel callback in done(err,user);modo che il codice sopra riportato passport.session()possa sostituire il valore 'utente' nell'oggetto req e passare al middleware successivo nella pila.


hey, come posso memorizzare i dettagli dell'utente solo nella sessione, non voglio salvarli nel database direttamente
Newbiee

1
"nelle intestazioni della richiesta"? non solo nell'oggetto richiesta
caub

Ho notato che se la strategia di sessione è in grado di ripristinare l'autenticazione e deserializzare l'utente. Ma nonostante ciò l'autenticazione si sposta ancora alla strategia successiva, che è l'autenticazione di Facebook nel mio scenario. Mi chiedo qual è lo scopo della strategia di sessione se continua a richiamare le seguenti strategie anche quando la sessione è in grado di recuperare l'utente.
nishant

15

Dalla documentazione

In un'applicazione basata su Connect o Express, il middleware passport.initialize () è necessario per inizializzare Passport. Se l'applicazione utilizza sessioni di accesso persistenti, è necessario utilizzare anche il middleware passport.session ().

e

sessioni

In una tipica applicazione web, le credenziali utilizzate per autenticare un utente verranno trasmesse solo durante la richiesta di accesso. Se l'autenticazione ha esito positivo, verrà stabilita e mantenuta una sessione tramite un cookie impostato nel browser dell'utente.

Ogni richiesta successiva non conterrà le credenziali, ma piuttosto il cookie univoco che identifica la sessione. Per supportare le sessioni di accesso, Passport serializzerà e deserializzerà le istanze utente da e verso la sessione.

e

Notare che l'abilitazione del supporto della sessione è del tutto opzionale, sebbene sia consigliato per la maggior parte delle applicazioni. Se abilitato, assicurarsi di utilizzare express.session () prima di passport.session () per assicurarsi che la sessione di accesso venga ripristinata nell'ordine corretto.


1
Grazie per la tua rapida risposta ma questo non risponde alla mia domanda. Inoltre, tieni presente che se hai un'applicazione express e usi express.session (), su qualsiasi client che si connette al tuo server express (che sia autenticato o meno), gli verrà assegnata una sessione tramite un cookie. Ciò è indipendente dal fatto che si trovi o meno in una pagina protetta da login della tua app. Vorrei comunque conoscere la differenza tra i due middleware.
Georges Krinker

1
@GeorgesKrinker sono i metodi serializeUser () e deserializeUser. Il middleware express ripristinerà le informazioni sulla sessione, ma non è necessariamente correlato al modo in cui passport gestisce le informazioni dell'utente. Questo deve essere fatto dopo che la sessione è stata reidratata da express.
Josh C.

Bene, avevo l'impressione che i metodi serializeUser () e deserializeUser funzionassero su authenticate () all'interno delle rotte.
Georges Krinker

@ GeorgesKrinker Non la penso così. Quando ho usato passport, ho chiamato solo .authenticate al login.
Josh C.

app.post('/login', passport.authenticate('local'), ...
Josh C.

11

Sebbene utilizzerai PassportJsper convalidare l'utente come parte dell'URL di accesso, hai ancora bisogno di un meccanismo per memorizzare queste informazioni utente nella sessione e recuperarle con ogni richiesta successiva (ad esempio serializzare / deserializzare l'utente).

Quindi, in effetti, stai autenticando l'utente con ogni richiesta, anche se questa autenticazione non ha bisogno di cercare un database o oauth come nella risposta di accesso. Quindi passport tratterà l'autenticazione della sessione anche come un'altra strategia di autenticazione.

E per usare questa strategia - che prende il nome session, basta usare una semplice scorciatoia - app.use(passport.session()). Si noti inoltre che questa particolare strategia richiederà di implementare funzioni di serializzazione e deserializzazione per ovvie ragioni.


11

Si autentica semplicemente la sessione (che è popolata da express.session()). È equivalente a:

passport.authenticate('session');

come si può vedere nel codice qui:

https://github.com/jaredhanson/passport/blob/42ff63c/lib/authenticator.js#L233


6
Cosa intendi? Viene eseguito su ogni richiesta e non dispone necessariamente di credenziali per l'autenticazione. Ti dispiacerebbe fornirmi qualche dettaglio in più sul flusso di lavoro che si verifica su ogni richiesta?
Georges Krinker

6
Sì, funziona su ogni richiesta. L'ID di sessione generato da Express è un ID univoco che equivale all'incirca a un token di autenticazione che il browser invia con ogni richiesta. I dati memorizzati in questa sessione vengono utilizzati per ripristinare lo stato di autenticazione dell'utente.
Jared Hanson,

Ciao @JaredHanson, potresti dare un'occhiata a questo . Non sono riuscito a trovare la risposta da nessuna parte?
Saras Arya

@ JaredHanson Sto cercando di utilizzare passport.js per autenticarmi con un server di autorizzazione open source ampiamente utilizzato che è conforme a OAuth2. Ma ricevo un errore. Sei disposto ad aiutare a risolvere il problema? Ecco il link: stackoverflow.com/questions/38176236/...
DollarCoffee

@ JaredHanson: Quello che osservo è che l'oggetto req aumentato con passport.user info subito dopo il login tramite google-oauth, viene perso quando viene effettuata la successiva richiesta di una nuova pagina sul sito. È questo il comportamento previsto? Allora non so come recuperare le informazioni dell'utente che ha effettuato l'accesso di recente?
user1102171
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.