Estoy usando node con express + mongoose e intento usar passport.js con restful api.
Sigo recibiendo esta excepción después del éxito de la autenticación (veo la URL de devolución de llamada en el navegador):
/Users/naorye/dev/naorye/myproj/node_modules/mongoose/lib/utils.js:419
throw err;
^
Error: passport.initialize() middleware not in use
at IncomingMessage.req.login.req.logIn (/Users/naorye/dev/naorye/myproj/node_modules/passport/lib/passport/http/request.js:30:30)
at Context.module.exports.delegate.success (/Users/naorye/dev/naorye/myproj/node_modules/passport/lib/passport/middleware/authenticate.js:194:13)
at Context.actions.success (/Users/naorye/dev/naorye/myproj/node_modules/passport/lib/passport/context/http/actions.js:21:25)
at verified (/Users/naorye/dev/naorye/myproj/node_modules/passport-facebook/node_modules/passport-oauth/lib/passport-oauth/strategies/oauth2.js:133:18)
at Promise.module.exports.passport.use.GitHubStrategy.clientID (/Users/naorye/dev/naorye/myproj/config/passport.js:91:24)
at Promise.onResolve (/Users/naorye/dev/naorye/myproj/node_modules/mongoose/node_modules/mpromise/lib/promise.js:162:8)
at Promise.EventEmitter.emit (events.js:96:17)
at Promise.emit (/Users/naorye/dev/naorye/myproj/node_modules/mongoose/node_modules/mpromise/lib/promise.js:79:38)
at Promise.fulfill (/Users/naorye/dev/naorye/myproj/node_modules/mongoose/node_modules/mpromise/lib/promise.js:92:20)
at /Users/naorye/dev/naorye/myproj/node_modules/mongoose/lib/query.js:1822:13
He leído que debería poner app.use(passport.initialize());
y app.use(passport.session());
antes app.use(app.router);
y esto es lo que hice. Aquí está mi express.js que registra los middlewares:
var express = require('express'),
mongoStore = require('connect-mongo')(express),
flash = require('connect-flash'),
helpers = require('view-helpers');
module.exports = function (app, config, passport) {
app.set('showStackError', true);
// should be placed before express.static
app.use(express.compress({
filter: function (req, res) {
return /json|text|javascript|css/.test(res.getHeader('Content-Type'));
},
level: 9
}));
app.use(express.favicon());
app.use(express.static(config.root + '/public'));
app.use(express.logger('dev'));
// set views path, template engine and default layout
app.set('views', config.root + '/app/views');
app.set('view engine', 'jade');
app.configure(function () {
// use passport session
app.use(passport.initialize());
app.use(passport.session());
// dynamic helpers
app.use(helpers(config.app.name));
// cookieParser should be above session
app.use(express.cookieParser());
// bodyParser should be above methodOverride
app.use(express.bodyParser());
app.use(express.methodOverride());
// express/mongo session storage
app.use(express.session({
secret: 'linkit',
store: new mongoStore({
url: config.db,
collection : 'sessions'
})
}));
// connect flash for flash messages
app.use(flash());
// routes should be at the last
app.use(app.router);
// assume "not found" in the error msgs
// is a 404. this is somewhat silly, but
// valid, you can do whatever you like, set
// properties, use instanceof etc.
app.use(function(err, req, res, next){
// treat as 404
if (~err.message.indexOf('not found')) {
return next();
}
// log it
console.error(err.stack);
// error page
res.status(500).render('500', { error: err.stack });
});
// assume 404 since no middleware responded
app.use(function(req, res, next){
res.status(404).render('404', {
url: req.originalUrl,
error: 'Not found'
});
});
});
};
¿Qué está mal?
ACTUALIZACIÓN De acuerdo con @Peter Lyons, he cambiado el orden de las configuraciones al siguiente, pero sigo teniendo el mismo error:
var express = require('express'),
mongoStore = require('connect-mongo')(express),
flash = require('connect-flash'),
helpers = require('view-helpers');
module.exports = function (app, config, passport) {
app.set('showStackError', true);
// should be placed before express.static
app.use(express.compress({
filter: function (req, res) {
return /json|text|javascript|css/.test(res.getHeader('Content-Type'));
},
level: 9
}));
app.use(express.favicon());
app.use(express.static(config.root + '/public'));
app.use(express.logger('dev'));
// set views path, template engine and default layout
app.set('views', config.root + '/app/views');
app.set('view engine', 'jade');
app.configure(function () {
// dynamic helpers
app.use(helpers(config.app.name));
// cookieParser should be above session
app.use(express.cookieParser());
// bodyParser should be above methodOverride
app.use(express.bodyParser());
app.use(express.methodOverride());
// express/mongo session storage
app.use(express.session({
secret: 'linkit',
store: new mongoStore({
url: config.db,
collection : 'sessions'
})
}));
// connect flash for flash messages
app.use(flash());
// use passport session
app.use(passport.initialize());
app.use(passport.session());
// routes should be at the last
app.use(app.router);
// assume "not found" in the error msgs
// is a 404. this is somewhat silly, but
// valid, you can do whatever you like, set
// properties, use instanceof etc.
app.use(function(err, req, res, next){
// treat as 404
if (~err.message.indexOf('not found')) {
return next();
}
// log it
console.error(err.stack);
// error page
res.status(500).render('500', { error: err.stack });
});
// assume 404 since no middleware responded
app.use(function(req, res, next){
res.status(404).render('404', {
url: req.originalUrl,
error: 'Not found'
});
});
});
};
Respuestas:
Siga el ejemplo para evitar el infierno del middleware fuera de servicio que hace que Express sea tan fácil de ingresar. Directamente de los documentos. Tenga en cuenta que el suyo no coincide exactamente con esto.
Docs
Tú
fuente
app.get
,app.post
, etc? Esos harán que el enrutador se agregue a la pila antes de lo previsto. Muéstrenos TODO el código relevante comenzando con cuando invoca laexpress()
función para obtener suapp
objeto. Esa es mi segunda suposición.En mi caso (mismo mensaje de error) me olvidé de agregar las inicializaciones del pasaporte:
ACTUALIZACIÓN: Solo funciona hasta Express versión 3, la versión 4 ya no es compatible con app.configure ()
fuente
En mi caso, el error se debió a que estaba tratando de prometer
req.login
sin vincularmethis
areq
, por lo que cuando se llamó a la función no pudo encontrar lapassport
configuración. La solución es vinculantereq.login.bind(req)
antes de pasarla apromisify
si está utilizando Node v8.fuente
function({ login })
pasar elreq
primer argumento. Su solución funcionó para mí, graciasthis
funciona en Javascript. Si no llama a la función como método de objeto,this
seráundefined
(owindow
en el navegador)Function.prototype.call
,Function.prototype.apply
cómothis
funciona en Javascript y los principios detrás de la herencia prototípica, ascenderá al nivel de Javascript Guru en el proceso :)util.promisify(req.login.bind(req));
Lo que me ayudó también fue poner rutas DESPUÉS de la configuración de las cookies :
fuente
La respuesta de Peter Lyons me ayudó a resolverlo, pero lo resolví de una manera un poco diferente.
Eche un vistazo a mi repositorio de GitHub para ver todo el código y no solo el fragmento de código aquí.
fuente
En mi caso (mismo mensaje de error), estaba desarrollando una estrategia personalizada y no necesito usar una sesión . Me olvidé de agregar
session: false
en mi rutaauthenticate
middleware.fuente