【问题标题】:NodeJS PassportNodeJS 护照
【发布时间】:2012-09-13 18:04:22
【问题描述】:

我在 nodejs 上设置了护照,并让它与 mongoose 一起工作,以允许用户登录和创建新帐户。

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.authencate() 函数。

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

【问题讨论】:

  • 在那里添加了一些代码。基本上我希望将其转移到外部路由文件并从 app.js 中删除混乱。
  • 你也可以发布 app.js v2 吗?可能问题是模块看不到您在 app.js 中创建的护照对象。您正在通过应用程序,但不是护照。试试看:module.exports = function(app, passport){...
  • app.js 2 和上面的一样减去护照功能。我仍然包括 passport = require('passport') 和 app.use 会话功能。我已经尝试过传递护照对象,但这也不起作用。我认为当您在 app.js 中配置护照时,它会在全局范围内?

标签: node.js mongoose passport.js


【解决方案1】:

这就是我所做的。如果您需要更多帮助以适应您的代码,请发表评论。

第一步

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

module.exports = function(passport, LocalStrategy){

};

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

第二步

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

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

说明

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

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

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

};

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

这应该有效。不久前我在谷歌上搜索过这个问题,这似乎是分解你的 app.js 的“正确”方式(尽管我非常恐惧地说:))。如果您需要更多帮助,请随时发表评论。

【讨论】:

  • @DanyZift :很高兴知道它有帮助!
  • @传奇天才!谢谢!
【解决方案2】:

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

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

server.js 文件将是您的 app.js。 /config/passport.js 是包含的护照设置。

【讨论】:

    【解决方案3】:

    为此,我建议在 app.js 中执行此操作

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

    并且 我的护照.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);
            });
          });
    } 
    ));
    }
    

    【讨论】:

      【解决方案4】:
      module.exports = function(app){
      
      passport.serializeUser(function(user, done) {
          done(null, user.id);
      });
      

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

      【讨论】:

        【解决方案5】:

        补充勒让德的答案。 module.exports = function() 是 nodejs 中使文件、变量或特定功能对整个应用程序全局可用的一种方式。

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

        【讨论】:

          猜你喜欢
          • 2023-04-06
          • 1970-01-01
          • 2016-03-18
          • 2018-10-14
          • 1970-01-01
          • 2015-04-11
          • 2017-02-20
          • 2014-10-09
          • 2018-03-15
          相关资源
          最近更新 更多