2013-03-30 1 views
30

Vorrei utilizzare passport.js per verificare che quando gli utenti colpiscono determinati endpoint che non solo abbiano la password corretta ma siano membri di un gruppo specifico o abbiano un determinato accesso.Verifica access/group in Passport.js

Per semplicità, se si dispone dei livelli di accesso di USER e AMMINISTRATORE.

posso utilizzare il passaporto per autenticare una password:

passport.use(new LocalStrategy(
    function(username, password, done) { 
    User.findOne({ username: username }, function(err, user) { 
     if (err) { return done(err); } 
     if (!user) { 
     return done(null, false, { message: 'Incorrect username.' }); 
     } 
     if (!user.validPassword(password)) { 
     return done(null, false, { message: 'Incorrect password.' }); 
     } 
     return done(null, user); 
    }); 
    } 
)); 

Poi, con un percorso che posso fare in modo che l'utente passa auth:

app.get('/api/users', 
    passport.authenticate('local'), 
    function(req, res) { 
    res.json({ ... }); 
    }); 

Ma permette di dire è necessario avere ADMIN acess hit/api/users '. Devo scrivere le mie strategie? Devo avere una strategia di local-user e local-admin, e in ogni verifica i livelli di accesso corretti?

Penso di poterlo fare abbastanza facilmente, ma il problema sorge quando ho bisogno che il mio sito abbia metodi di autenticazione diversi (forse a volte uso oauth), avrei bisogno di scrivere strategie personalizzate * -user, * -admin per ogni . Sembra eccessivo.

Un'altra opzione è verificare l'accesso/gruppo in ogni percorso dopo che l'utente è stato autenticato. Ma preferirei farlo nella middleware se possibile.

Grazie

risposta

50

Si potrebbe creare un semplice middleware che controlla il gruppo:

var needsGroup = function(group) { 
    return function(req, res, next) { 
    if (req.user && req.user.group === group) 
     next(); 
    else 
     res.send(401, 'Unauthorized'); 
    }; 
}; 

app.get('/api/users', 
    passport.authenticate('local'), 
    needsGroup('admin'), 
    function(req, res) { 
    ... 
    }); 

Ciò presuppone che l'oggetto memorizzato in req.user ha una proprietà group. Questo oggetto è quello passato dall'implementazione della strategia e deserializeUser.

Un'alternativa potrebbe essere connect-roles, ma non so quanto bene si integra con Passport.

EDIT: si potrebbe anche combinare passaporto e il gruppo-controllo middleware:

var needsGroup = function(group) { 
    return [ 
    passport.authenticate('local'), 
    function(req, res, next) { 
     if (req.user && req.user.group === group) 
     next(); 
     else 
     res.send(401, 'Unauthorized'); 
    } 
    ]; 
}; 

app.get('/api/users', needsGroup('admin'), function(req, res) { 
}); 
+0

Oh, capisco. Sembra che sia possibile utilizzare una serie di funzioni di "middleware" chiamate in ordine con express. Non l'ho nemmeno capito, deve averlo perso. È ora di leggere di nuovo il manuale;) Grazie, è perfetto! – lostintranslation

+2

Sì, eccolo: "app.VERB (path, [callback ...], callback)". Mi dispiace, mi sono perso e grazie per essere stato così gentile con la tua risposta! – lostintranslation

+0

È un utile 'trucco' Continuo a dimenticarmi :) – robertklep