【问题标题】:How do I correctly call passport.js functions with express router?如何使用 express 路由器正确调用 passport.js 函数?
【发布时间】:2015-05-01 14:17:23
【问题描述】:

我正在尝试调用 passport.authenticate 函数来响应我的注册视图的发布请求。我一直关注this tutorial here 来了解passport.js 和express,但是已经完成了第一页的说明并对express.js 4.0 进行了必要的更改,我尝试访问的每个页面都返回错误500 并显示以下堆栈跟踪:

TypeError: Object #<serverResponse> has no method 'authenticate'
    at module.exports (/home/myUserName/Desktop/manufacturing/routes/index.js:66:37)
    at Layer.handle [as handle_request] (/home/myUserName/Desktop/manufacturing/node_modules/express/lib/router/layer.js:82:5)
    at trim_prefix (/home/myUserName/Desktop/manufacturing/node_modules/express/lib/router/index.js:302:13)
    at /home/myUserName/Desktop/manufacturing/node_modules/express/lib/router/index.js:270:7
    at Function.proto.process_params (/home/myUserName/Desktop/manufacturing/node_modules/express/lib/router/index.js:321:12)
    at next (/home/myUserName/Desktop/manufacturing/node_modules/express/lib/router/index.js:261:10)
    at /home/myUserName/Desktop/manufacturing/node_modules/connect-flash/lib/flash.js:21:5
    at Layer.handle [as handle_request] (/home/myUserName/Desktop/manufacturing/node_modules/express/lib/router/layer.js:82:5)
    at trim_prefix (/home/myUserName/Desktop/manufacturing/node_modules/express/lib/router/index.js:302:13)
    at /home/myUserName/Desktop/manufacturing/node_modules/express/lib/router/index.js:270:7

这里是 /routes/index.js 的代码:

var express = require('express');
var bodyParser = require('body-parser');
var router = express.Router();

module.exports = function(app, passport) {
  /* GET home page. */
  router.get('/', function(req, res, next) {
    res.render('index', {
      title: 'Home Page'
    });
  });

  /* GET about page */
  router.get('/about', function(req, res, next) {
    res.render('about', {
      title: 'About Us'
    });
  });

  /* GET contact page */
  router.get('/contact', function(req, res, next) {
    res.render('contact', {
      title: 'Contact Us'
    });
  });

  /* GET login page */
  router.get('/login', function(req, res, next) {
    res.render('login', {
      title: 'User Login',
      message: req.flash('loginMessage')
    });
  });

  /* GET register page */
  router.get('/register', function(req, res, next) {
    res.render('register', {
      title: 'User Registration',
      message: req.flash('signupMessage')
    });
  });

  /* POST register page */
  router.post('/register', passport.authenticate('local', {
    successRedirect : '/',
    failureRedirect : '/register',
    failureFlash    : true
  }));

  /* Log Out */

  router.get('/logout', function(req, res, next) {
    req.logout();
    res.redirect('/');
  });

  /* 404 - page not found */
  router.get('*', function(req, res){
    res.render('404', {
      title: '404 - Not Found'
    });
  });

  // Route middleware to make sure a user is logged in
  function isLoggedIn(req, res, next) {
    if (req.isAuthenticated())
      return next();
    res.redirect('/');
  };
};

这是我的 server.js:

var express       = require('express');
var path          = require('path');
var logger        = require('morgan');
var mongoose      = require('mongoose');
var bodyParser    = require('body-parser');
var cookieParser  = require('cookie-parser');
var session       = require('express-session');
var passport      = require('passport');
var flash         = require('connect-flash');

// Database

var configDB = require('./config/database.js');
mongoose.connect(configDB.url);
require('./config/passport')(passport); 

// Routes
var routes = require('./routes/index');

var port = process.env.PORT || 3000;
var app = express();

// Express configuration
app.use(logger('dev')); // log every request to console
app.use(bodyParser.json()); // get information from html forms
  app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser()); // read cookies (needed for auth)
app.use(express.static(path.join(__dirname, 'public')));

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
if (app.get('env') === 'development') {
  app.locals.pretty = true;
}

// Passport configuration

app.use(session({ secret: 'MySecretHere',
                  saveUninitialized: true,
                  resave: true})); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash()); // use connect-flash for flash messages stored in session

app.use('/', routes);

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
    app.use(function(err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
            message: err.message,
            error: err
        });
    });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
        message: err.message,
        error: {}
    });
});

app.listen(port);
console.log('Server running on ' + port);

【问题讨论】:

    标签: javascript node.js express passport.js passport-local


    【解决方案1】:

    您收到错误的原因是因为您导出了一个将apppassport 作为http 处理程序参数的函数,但是当您在server.js 中需要它时,您没有传递passportapp

    您需要以某种方式将passport 传递给require。 您可以将您的路线文件更改为 如果您使用的是express.Router

       var router = express.Router();
       module.exports = function(passport) {
           // init your routes with passport and router
           router.post('/' function(req, res) {
              //...
           });
          // make sure to return router in the function though
          return router;
       }
    

    如果不使用express.Router,您可以同时传递apppassport 并将处理程序附加到app

       module.exports = function (app, passport) {
           app.post('/', function(req, res) {
             //...
           });
           // no need to return app
       }
    

    然后在 server.js 中

         // if your using `express.Router()` in routes file
         app.use('/', require('./routes')(passport));
         // If your registering handler on app itself just bootstrap it
         require('./routes')(app, passport);
    

    【讨论】:

    • 这个答案是有道理的,但是当我尝试它时,npm start 失败并出现以下错误:TypeError: Object function (req, res, next) { app.handle(req, res, next); } has no method 'authenticate'
    • 这很有趣,我想我可能明白发生了什么。尝试在路由文件的导出函数中返回router。生病编辑我的答案。
    • 所以我很确定它抛出了一个错误,因为app.use 需要一个 http 处理程序作为参数,但是路由文件没有在导出的函数中返回 router
    • handler 应该在哪里定义?无论我同时传递apppassport,还是尝试将处理程序附加到app,应用程序都无法在我的路由文件中引用handler
    • 抱歉,这只是举例说明如何分别为approuter 注册“处理程序”。 handler 不需要定义。
    【解决方案2】:

    您需要将护照传递到您的路线。您可以通过这种方式更改您的代码:

    /routes/index.js
    来自module.exports = function(app, passport) {...}
    module.exports = function(passport){ return function(app) {...}}

    /server.js
    来自app.use('/', routes);
    app.use('/', routes(passport));

    【讨论】:

    • 您能解释一下为什么需要将 app 作为函数返回吗?当我尝试进行更改时,应用程序启动正常,但如果我尝试加载页面,它只会显示“等待本地主机......”并且永远不会到达任何地方。控制台也不记录任何内容。
    • 下一步修改应该有帮助 module.exports = function(passport){ ... return router;如果要包含来自 server.js 的路由,例如 app.use('/', routes(passport));,则不需要传递“app”
    猜你喜欢
    • 2015-09-03
    • 1970-01-01
    • 2014-08-18
    • 1970-01-01
    • 2019-02-28
    • 1970-01-01
    • 1970-01-01
    • 2021-03-07
    • 1970-01-01
    相关资源
    最近更新 更多