2012-09-21 50 views
22

Configuré el pasaporte en nodejs y lo tengo trabajando con mangosta para permitir a los usuarios iniciar sesión y crear cuentas nuevas.NodeJS Passport

app.js:

var express = require('express') 
    , app = module.exports = express.createServer() 
    , passport = require('passport') 
    , LocalStrategy = require('passport-local').Strategy 
    , routes = require('./routes/index')(app) //index loads in multiple routes 
    , MongoDBConnection = require('./database/DatabaseConnector').MongoDBConnection; 

// Configuration 
app.configure(function(){ 
    app.set('views', __dirname + '/views'); 
    app.set('view engine', 'jade'); 
    app.use(express.cookieParser()); 
    app.use(express.bodyParser()); 
    app.use(express.methodOverride()); 
    app.use(express.session({ secret: 'justdoit' })); 
    app.use(passport.initialize()); 
    app.use(passport.session()); 
    app.use(app.router); 
    app.use(express.static(__dirname + '/public')); 
}); 

var mongoDbConnection = new MongoDBConnection(); 

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

passport.deserializeUser(function(id, done) { 
    mongoDbConnection.findUserById(id, function(err, user){ 
     done(err, user); 
    }); 
}); 

passport.use(new LocalStrategy(
    function(username, password, done) { 
     process.nextTick(function() { 
      mongoDbConnection.findUser(username, function(err, user) { 
       //conditions.... 
      }); 
     }); 
    } 
)); 

app.get('/', function(req, res){ 
    res.render('index', { title: "Index", user: req.user }); 
}); 

app.get('/account', ensureAuthenticated, function(req, res){ 
    res.render('account', { title: "Account", user: req.user }); 
}); 

app.get('/login', function(req, res){ 
    res.render('login', { title: "Login", user: req.user, message: req.flash('error') }); 
}); 

app.post('/login', 
    passport.authenticate('local', { 
     successRedirect: '/account', 
     failureRedirect: '/login', 
     failureFlash: true }) 
); 

function ensureAuthenticated(req, res, next) { 
    if (req.isAuthenticated()) { return next(); } 
    res.redirect('/login') 
} 

Mi problema es el app.js (que es donde el código pasaporte es) de archivos es cada vez un poco grande y yo tratamos de mover las secciones de pasaporte en su escritura, ya tener las rutas fuera de la aplicación.js y en su propio archivo de ruta auth.js y luego hacer referencia a las rutas a través de la aplicación.js. Funciona para otras rutas, pero para las relacionadas con el pasaporte, como iniciar sesión, parece que no activa la función pasaporte.authenicate().

¿Hay alguna forma en que pueda poner rutas y funciones de pasaporte en su propio archivo y llamarlo/cargarlo desde app.js?

auth.js:

module.exports = function(app){ 

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

passport.deserializeUser(function(id, done) { 
    mongoDbConnection.findUserById(id, function(err, user){ 
     done(err, user); 
    }); 

}); 

passport.use(new LocalStrategy(
    function(username, password, done) { 
     process.nextTick(function() { 

      mongoDbConnection.findUser(username, function(err, user) { 

       if (err) { 
        return done(err); 
       } 
       if (!user) { 
        return done(null, false, { message: 'Unknown user ' + username }); 
       } 

       if (user.password != password) { 
        return done(null, false, { message: 'Invalid password' }); 
       } 

       return done(null, user); 
      }); 
     }); 
    } 
)); 

app.get('/', function(req, res){ 
    res.render('index', { title: "Index", user: req.user }); 
}); 

app.get('/account', ensureAuthenticated, function(req, res){ 
    console.log("directing to the account page...."); 
    res.render('account', { title: "Account", user: req.user }); 
}); 

app.get('/login', function(req, res){ 
    res.render('login', { title: "Login", user: req.user, message: req.flash('error') }); 
}); 

app.post('/login', 
    passport.authenticate('local', { 
     successRedirect: '/account', 
     failureRedirect: '/login', 
     failureFlash: true }) 
); 

function ensureAuthenticated(req, res, next) { 
    if (req.isAuthenticated()) { return next(); } 
    res.redirect('/login') 
} 
} 
+0

¿Puede usted publicar un código? – UpTheCreek

+0

Agregó un código allí. Básicamente estoy buscando cambiarlo a un archivo de ruta externo y eliminar el desorden de app.js. – DanyZift

+0

¿Puedes publicar el app.js v2 también? Probablemente el problema es que el módulo no puede ver el objeto pasport creado en la aplicación.js. Estás aprobando la aplicación, pero no el pasaporte. Pruebe: 'module.exports = function (app, pasaporte) {...' – UpTheCreek

Respuesta

36

Esto es lo que hago. Comente si necesita más ayuda para adaptarlo a su código.

primer paso

Ponga su código de pasaporte en un archivo separado. p.ej. pass.js. (Veo que ya has hecho eso) Entonces, en ese archivo, poner todo el código dentro de este:

module.exports = function(passport, LocalStrategy){ 

}; 

no olvide añadirlo a la entrada de la función nada más que usted está utilizando. En su caso, además del pasaporte y la Estrategia Local, probablemente necesite agregar mongoDbConnection también como entrada.

Segundo Paso

En sus app.js, incluya esta línea. Justo antes de "app.listen", si es posible, para asegurarse de que todo se haya definido/declarado/incluido correctamente.

require('./pass.js')(passport, LocalStrategy); 

Explicación

El "contenedor" en el paso uno define el trozo de código que será incluido en su aplicación. El "requerir" en el paso dos es el código que realmente lo incluye. Básicamente está definiendo el archivo "pass.js" completo como una función y pasándole las herramientas que necesita para llevar a cabo el código (pasaporte, LocalStrategy, etc.)

En su caso, es probable que necesite modificar mi código para :

module.exports = function(passport, LocalStrategy, mongoDbConnection){ 

}; 

require('./pass.js')(passport, LocalStrategy, mongoDbConnection); 

Esto debería funcionar. Busqué en Google sobre esto hace un tiempo y esta parece ser la forma "correcta" de romper tu app.js (aunque lo digo con gran inquietud :)). Siéntase libre de comentar si necesita más ayuda.

+0

Saludos Legendre, que hizo el truco. :) – DanyZift

+0

@DanyZift: ¡Muy contento de saber que ayudó! – Legendre

+0

@Legendre Genius! ¡Gracias! – shaunakde

3

Para esto, le sugiero que haga esto en la aplicación.js

require('./mypassport')(app); 

Y mypassport.js

var passport = require('passport') 
, LocalStrategy = require('passport-local').Strategy 

, MongoDBConnection = require('./database/DatabaseConnector').MongoDBConnection; 

    module.exports = function(app){ 

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

    passport.deserializeUser(function(id, done) { 
    mongoDbConnection.findUserById(id, function(err, user){ 
    done(err, user); 
    }); 

}); 

passport.use(new LocalStrategy(
function(username, password, done) { 
    process.nextTick(function() { 

     mongoDbConnection.findUser(username, function(err, user) { 

      if (err) { 
       return done(err); 
      } 
      if (!user) { 
       return done(null, false, { message: 'Unknown user ' + username }); 
      } 

      if (user.password != password) { 
       return done(null, false, { message: 'Invalid password' }); 
      } 

       return done(null, user); 
     }); 
     }); 
} 
)); 
} 
0
module.exports = function(app){ 

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

Tal vez no funciona porque u no tiene una referencia a un objeto de pasaporte?

0

Agregando a la respuesta de Legendre. module.exports = function() es una manera en nodejs de hacer que un archivo, una variable o una determinada funcionalidad esté disponible globalmente para toda la aplicación.

// anyfile.js 
    module.exports = function(){ 
    //global code. 
}