NodeJS Passport

时间:2012-09-21 10:07:01

标签: node.js mongoose passport.js

我在nodejs上设置了护照并让它与m​​ongoose一起使用,以允许用户登录并创建新帐户。

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')
}

我的问题是app.js(这是护照代码所在的位置)文件变得有点大,我试图将护照部分移动到自己的脚本中,并将路径放在app.js之外和自己的路径中auth.js路由文件,然后通过app.js引用路由。它适用于其他路线,但对于护照相关的路线,如登录它似乎不会触发passport.authenicate()函数。

无论如何我可以将护照路由和功能放入自己的文件中并从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')
}
}

4 个答案:

答案 0 :(得分:36)

这就是我的工作。如果您需要更多帮助来定制代码,请发表评论。

第一步

将护照代码放在单独的文件中。例如pass.js. (我看到你已经这样做了)然后,在那个文件中,将所有代码放在这里:

module.exports = function(passport, LocalStrategy){

};

请记住向函数输入添加您正在使用的任何其他内容。在您的情况下,除了护照和LocalStrategy之外,您可能还需要添加mongoDbConnection作为输入。

第二步

在你的app.js中,包括这一行。就在“app.listen”之前,如果可能的话,确保所有内容都已正确定义/声明/包含。

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

<强>解释

第一步中的“包装器”定义了将包含在应用程序中的代码块。第二步中的“require”是实际包含它的代码。您基本上将整个“pass.js”文件定义为函数,并将其传递给执行代码所需的工具(护照,LocalStrategy等)

在您的情况下,您可能需要将我的代码修改为:

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

};

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

这应该有效。我前一段时间用谷歌搜索了这个,这似乎是打破你的app.js的“正确”方式(虽然我非常惶恐地说:)但是:)。如果您需要帮助,请随时发表评论。

答案 1 :(得分:6)

这个github回购也有一个很好的例子。

https://github.com/madhums/nodejs-express-mongoose-demo

server.js文件将是你的app.js. /config/passport.js是随附的护照设置。

答案 2 :(得分:3)

为此,我建议在app.js

中执行此操作
 require('./mypassport')(app);

和 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);
        });
      });
} 
));
}

答案 3 :(得分:0)

module.exports = function(app){

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

也许它不起作用,因为你没有对护照对象的引用?