im после этого урока для работы с аутентификацией с узлом.js и у меня есть некоторые проблемы, которые я еще не понял, как решить. В основном я устанавливаю сервер так
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
}));
}
чтобы закончить это, мне нужно показать, как установлен мой паспорт, я не очень хорошо знаю, что я пропускаю здесь, и почему я получаю эту ошибку, может быть, это имеет какое-то отношение к порядку middlewares?
паспорт
/ 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:UsersFilipeShareIdeanode_modulespath-to-regexpindex
.js:128:10)
at new Layer (C:UsersFilipeShareIdeanode_modulesexpresslibrouterlaye
r.js:45:17)
at Function.route (C:UsersFilipeShareIdeanode_modulesexpresslibrouter
index.js:494:15)
at EventEmitter.app.(anonymous function) [as post] (C:UsersFilipeShareIde
anode_modulesexpresslibapplication.js:480:30)
at module.exports (C:UsersFilipeShareIdearoutesroutes.js:14:10)
at Object.<anonymous> (C:UsersFilipeShareIdeaapp.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
Да, порядок middlewares имеет значение. Вы должны разместить эти:
app.use(bodyParser.json());
в верхней части ваших маршрутов или любого другого промежуточного программного обеспечения, которые должны получать данные, в противном случае любые данные, которые вы можете получить на вашем сервере , не будут проанализированыapp.use(bodyParser.urlencoded({ extended: true }));
body-parser
, иreq.body
всегда будут неопределенными.