繁体   English   中英

Router.use()需要中间件功能,但在使用功能时未定义

[英]Router.use() requires middleware function but got a undefined at function use

我按照本教程使用node.js进行身份验证,我遇到了一些我尚未弄清楚如何解决的问题。 Basicly我设置服务器这样

var express         = require('express');
var bodyParser      = require('body-parser'); // necessário para PUT e POST
var mongoose        = require('mongoose');
var expressLayouts  = require('express-ejs-layouts');
var passport        = require('passport');
var flash           = require('connect-flash');
var morgan          = require('morgan');
var cookieParser    = require('cookie-parser');
var session         = require('express-session');
var configDB        = require('./config/database.js');

// conexão à base de dados (o servidor MongoDB necessita já ter sido iniciado)
mongoose.Promise = global.Promise; //resolução de warning:
mongoose.connect(configDB.url);

//require('./config/passport')(passport); // pass passport for configuration

// Configura a aplicação Express (e seus middlewares)

var app = express();

app.use(morgan('dev')); // log every request to the console
app.use(cookieParser()); // read cookies (needed for auth)
app.use(bodyParser()); // get information from html forms

app.set('views', './views');
app.set('view engine','ejs');

app.use(session({ secret: 'ilovescotchscotchyscotchscotch' })); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash());

app.use(expressLayouts);
app.use(express.static('./public'));
app.use('/', require('./routes/register')(passport));
app.use('/', require('./routes/login')(passport));
app.use('/', require('./routes/profile')(passport));
app.use('/', require('./routes/main')(passport));
app.use('/', require('./routes/logout')(passport));

//middlewares de terceiros
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
//middlewares de roteamento

// inicia servidor
var server = app.listen(8081, function() {
 console.log('Express server listening on port ' + server.address().port);
});

我认为问题与我的路线或护照模块进行身份验证有关。

这是我的报名路线

var User = require('../models/user');
var express = require('express');
// routeamento do Express
var router = express.Router();
//GET request - /movies
module.exports = function(passport) {

    router.route('/register')
        .get(function(req, res) {
            res.render('./pages/register',{ message: req.flash('signupMessage') });
        })
        .post(passport.authenticate('local-signup', {
            successRedirect : '/profile', // redirect to the secure profile section
            failureRedirect : '/register', // redirect back to the signup page if there is an error
            failureFlash : true // allow flash messages
        }));
}

为此,我需要证明我的护照是如何设置的,我不太清楚我在这里丢失了什么,为什么我会收到该错误,也许与中间件的顺序有关?

护照

/ config/passport.js

// load all the things we need
var LocalStrategy   = require('passport-local').Strategy;
// load up the user model
var User            = require('../models/user');

// expose this function to our app using module.exports
module.exports = function(passport) {
    // =========================================================================
    // passport session setup ==================================================
    // =========================================================================
    // required for persistent login sessions
    // passport needs ability to serialize and unserialize users out of session

    // used to serialize the user for the session
    passport.serializeUser(function(user, done) {
        done(null, user.id);
    });

    // used to deserialize the user
    passport.deserializeUser(function(id, done) {
        User.findById(id, function(err, user) {
            done(err, user);
        });
    });

    // =========================================================================
    // LOCAL SIGNUP ============================================================
    // =========================================================================
    // we are using named strategies since we have one for login and one for signup
    // by default, if there was no name, it would just be called 'local'

    passport.use('local-signup', new LocalStrategy({
        // by default, local strategy uses username and password, we will override with email
        usernameField : 'email',
        passwordField : 'password',
        passReqToCallback : true // allows us to pass back the entire request to the callback
    },
    function(req, email, password, done) {

        // asynchronous
        // User.findOne wont fire unless data is sent back
        process.nextTick(function() {

        // find a user whose email is the same as the forms email
        // we are checking to see if the user trying to login already exists
        User.findOne({ 'local.email' :  email }, function(err, user) {
            // if there are any errors, return the error
            if (err)
                return done(err);

            // check to see if theres already a user with that email
            if (user) {
                return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
            } else {

                // if there is no user with that email
                // create the user
                var newUser            = new User();

                // set the user's local credentials
                newUser.local.email    = email;
                newUser.local.password = newUser.generateHash(password);

                // save the user
                newUser.save(function(err) {
                    if (err)
                        throw err;
                    return done(null, newUser);
                });
            }

        });    

        });

    }));

};

在cmd上的错误:

us);
        } else {
          var challenges = failures\.map(function(f) { return f\.challenge; });
          var statuses = failures\.map(function(f) { return f\.status; });
          return callback(null, false, challenges, statuses);
        }
      }

      \/\/ Strategies are ordered by priority\.  For the purpose of flashing a
      \/\/ message, the first failure will be displayed\.
      var failure = failures[0] || {}
        , challenge = failure\.challenge || {}
        , msg;

      if (options\.failureFlash) {
        var flash = options\.failureFlash;
        if (typeof flash == 'string') {
          flash = { type: 'error', message: flash };
        }
        flash\.type = flash\.type || 'error';

        var type = flash\.type || challenge\.type || 'error';
        msg = flash\.message || challenge\.message || challenge;
        if (typeof msg == 'string') {
          req\.flash(type, msg);
        }
      }
      if (options\.failureMessage) {
        msg = options\.failureMessage;
        if (typeof msg == 'boolean') {
          msg = challenge\.message || challenge;
        }
        if (typeof msg == 'string') {
          req\.session\.messages = req\.session\.messages || [];
          req\.session\.messages\.push(msg);
        }
      }
      if (options\.failureRedirect) {
        return res\.redirect(options\.failureRedirect);
      }

      \/\/ When failure handling is not delegated to the application, the defaul
t
      \/\/ is to respond with 401 Unauthorized\.  Note that the WWW-Authenticate

      \/\/ header will be set according to the strategies in use (see
      \/\/ actions#fail)\.  If multiple strategies failed, each of their challen
ges
      \/\/ will be included in the response\.
      var rchallenge = []
        , rstatus, status;

      for (var j = 0, len = failures\.length; j < len; j++) {
        failure = failures[j];
        challenge = failure\.challenge;
        status = failure\.status;

        rstatus = rstatus || status;
        if (typeof challenge == 'string') {
          rchallenge\.push(challenge);
        }
      }

      res\.statusCode = rstatus || 401;
      if (res\.statusCode == 401 && rchallenge\.length) {
        res\.setHeader('WWW-Authenticate', rchallenge);
      }
      if (options\.failWithError) {
        return next(new AuthenticationError(http\.STATUS_CODES[res\.statusCode],
 rstatus));
      }
      res\.end(http\.STATUS_CODES[res\.statusCode]);
    }

    (function attempt(i) {
      var layer = name[i];
      \/\/ If no more strategies exist in the chain, authentication has failed\.

      if (!layer) { return allFailed(); }

      \/\/ Get the strategy, which will be used as prototype from which to creat
e
      \/\/ a new instance\.  Action functions will then be bound to the strategy

      \/\/ within the context of the HTTP request\/response pair\.
      var prototype = passport\._strategy(layer);
      if (!prototype) { return next(new Error('Unknown authentication strategy "
' + layer + '"')); }

      var strategy = Object\.create(prototype);


      \/\/ ----- BEGIN STRATEGY AUGMENTATION -----
      \/\/ Augment the new strategy instance with action functions\.  These acti
on
      \/\/ functions are bound via closure the the request\/response pair\.  The
 end
      \/\/ goal of the strategy is to invoke (.*)one(.*) of these action methods
, in
      \/\/ order to indicate successful or failed authentication, redirect to a
      \/\/ third-party identity provider, etc\.

      \/(.*)(.*)
       (.*) Authenticate `user`, with optional `info`\.
       (.*)
       (.*) Strategies should call this function to successfully authenticate a
       (.*) user\.  `user` should be an object supplied by the application after
 it
       (.*) has been given an opportunity to verify credentials\.  `info` is an
       (.*) optional argument containing additional user information\.  This is
       (.*) useful for third-party authentication strategies to pass profile
       (.*) details\.
       (.*)
       (.*) @param {Object} user
       (.*) @param {Object} info
       (.*) @api public
       (.*)\/
      strategy\.success = function(user, info) {
        if (callback) {
          return callback(null, user, info);
        }

        info = info || {};
        var msg;

        if (options\.successFlash) {
          var flash = options\.successFlash;
          if (typeof flash == 'string') {
            flash = { type: 'success', message: flash };
          }
          flash\.type = flash\.type || 'success';

          var type = flash\.type || info\.type || 'success';
          msg = flash\.message || info\.message || info;
          if (typeof msg == 'string') {
            req\.flash(type, msg);
          }
        }
        if (options\.successMessage) {
          msg = options\.successMessage;
          if (typeof msg == 'boolean') {
            msg = info\.message || info;
          }
          if (typeof msg == 'string') {
            req\.session\.messages = req\.session\.messages || [];
            req\.session\.messages\.push(msg);
          }
        }
        if (options\.assignProperty) {
          req[options\.assignProperty] = user;
          return next();
        }

        req\.logIn(user, options, function(err) {
          if (err) { return next(err); }

          function complete() {
            if (options\.successReturnToOrRedirect) {
              var url = options\.successReturnToOrRedirect;
              if (req\.session && req\.session\.returnTo) {
                url = req\.session\.returnTo;
                delete req\.session\.returnTo;
              }
              return res\.redirect(url);
            }
            if (options\.successRedirect) {
              return res\.redirect(options\.successRedirect);
            }
            next();
          }

          if (options\.authInfo !== false) {
            passport\.transformAuthInfo(info, req, function(err, tinfo) {
              if (err) { return next(err); }
              req\.authInfo = tinfo;
              complete();
            });
          } else {
            complete();
          }
        });
      };

      \/(.*)(.*)
       (.*) Fail authentication, with optional `challenge` and `status`, default
ing
       (.*) to 401\.
       (.*)
       (.*) Strategies should call this function to fail an authentication attem
pt\.
       (.*)
       (.*) @param {String} challenge
       (.*) @param {Number} status
       (.*) @api public
       (.*)\/
      strategy\.fail = function(challenge, status) {
        if (typeof challenge == 'number') {
          status = challenge;
          challenge = undefined;
        }

        \/\/ push this failure into the accumulator and attempt authentication
        \/\/ using the next strategy
        failures\.push({ challenge: challenge, status: status });
        attempt(i + 1);
      };

      \/(.*)(.*)
       (.*) Redirect to `url` with optional `status`, defaulting to 302\.
       (.*)
       (.*) Strategies should call this function to redirect the user (via their

       (.*) user agent) to a third-party website for authentication\.
       (.*)
       (.*) @param {String} url
       (.*) @param {Number} status
       (.*) @api public
       (.*)\/
      strategy\.redirect = function(url, status) {
        \/\/ NOTE: Do not use `res\.redirect` from Express, because it can't dec
ide
        \/\/       what it wants\.
        \/\/
        \/\/       Express 2\.x: res\.redirect(url, status)
        \/\/       Express 3\.x: res\.redirect(status, url) -OR- res\.redirect(u
rl, status)
        \/\/         - as of 3\.14\.0, deprecated warnings are issued if res\.re
direct(url, status)
        \/\/           is used
        \/\/       Express 4\.x: res\.redirect(status, url)
        \/\/         - all versions (as of 4\.8\.7) continue to accept res\.redi
rect(url, status)
        \/\/           but issue deprecated versions

        res\.statusCode = status || 302;
        res\.setHeader('Location', url);
        res\.setHeader('Content-Length', '0');
        res\.end();
      };

      \/(.*)(.*)
       (.*) Pass without making a success or fail decision\.
       (.*)
       (.*) Under most circumstances, Strategies should not need to call this
       (.*) function\.  It exists primarily to allow previous authentication sta
te
       (.*) to be restored, for example from an HTTP session\.
       (.*)
       (.*) @api public
       (.*)\/
      strategy\.pass = function() {
        next();
      };

      \/(.*)(.*)
       (.*) Internal error while performing authentication\.
       (.*)
       (.*) Strategies should call this function when an internal error occurs
       (.*) during the process of performing authentication; for example, if the

       (.*) user directory is not available\.
       (.*)
       (.*) @param {Error} err
       (.*) @api public
       (.*)\/
      strategy\.error = function(err) {
        if (callback) {
          return callback(err);
        }

        next(err);
      };

      \/\/ ----- END STRATEGY AUGMENTATION -----

      strategy\.authenticate(req, options);
    })(0); \/\/ attempt
  }\/?$/: Nothing to repeat
    at RegExp (native)
    at pathtoRegexp (C:\Users\Filipe\ShareIdea\node_modules\path-to-regexp\index
.js:128:10)
    at new Layer (C:\Users\Filipe\ShareIdea\node_modules\express\lib\router\laye
r.js:45:17)
    at Function.route (C:\Users\Filipe\ShareIdea\node_modules\express\lib\router
\index.js:494:15)
    at EventEmitter.app.(anonymous function) [as post] (C:\Users\Filipe\ShareIde
a\node_modules\express\lib\application.js:480:30)
    at module.exports (C:\Users\Filipe\ShareIdea\routes\routes.js:14:10)
    at Object.<anonymous> (C:\Users\Filipe\ShareIdea\app.js:43:30)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:394:7)
    at startup (bootstrap_node.js:149:9)
    at bootstrap_node.js:509:3

是的,中间件的顺序很重要。 您应该放置这些: app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); 在路由或任何其他假设要接收数据的中间件上的顶部,否则body-parser不会解析您可能从服务器中获取的任何数据,并且req.body始终是未定义的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM