Estou usando o node com express + mongoose e tentando usar passport.js com api repousante.
Continuo recebendo essa exceção após o sucesso da autenticação (vejo o URL de retorno de chamada no 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
Li que deveria colocar app.use(passport.initialize());
e app.use(passport.session());
antes app.use(app.router);
e foi o que fiz. Aqui está meu express.js que registra os 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'
});
});
});
};
O que está errado?
ATUALIZAÇÃO De acordo com @Peter Lyons, mudei a ordem das configurações para o seguinte, mas ainda recebo o mesmo erro:
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'
});
});
});
};
Respostas:
Siga o exemplo para evitar o inferno de middleware fora de ordem que o express torna tão fácil de entrar. Direto dos documentos. Observe como o seu não corresponde exatamente a isso.
Docs
Vocês
fonte
app.get
,app.post
, etc? Isso fará com que o roteador seja adicionado à pilha antes do esperado. Mostre-nos TODOS o código relevante, começando com quando você invoca aexpress()
função para obter seuapp
objeto. Esse é meu segundo palpite.No meu caso (mesma mensagem de erro) esqueci de adicionar as inicializações do passaporte:
ATUALIZAÇÃO: Funcionando apenas até a versão expressa 3, a versão 4 não é mais compatível com app.configure ()
fonte
No meu caso o erro foi porque eu estava tentando promisify
req.login
sem vincularthis
areq
, então quando a função foi chamada ela não conseguiu encontrar aspassport
configurações. A solução é vinculativareq.login.bind(req)
antes de passá-lapromisify
se você estiver usando o Node v8.fonte
function({ login })
passar oreq
como primeiro argumento. A sua solução funcionou para mim, obrigadothis
funciona em Javascript. Se você não chamar a função como método de objeto,this
seráundefined
(ouwindow
no navegador)Function.prototype.call
,Function.prototype.apply
comothis
funciona em Javascript e os princípios por trás da herança prototípica, você irá promover ao nível de Javascript Guru no processo :)util.promisify(req.login.bind(req));
O que também me ajudou foi colocar as rotas APÓS a configuração dos cookies :
fonte
A resposta de Peter Lyons me ajudou a resolver, mas resolvi de uma maneira um pouco diferente.
Dê uma olhada em meu repositório GitHub para todo o código e não apenas o snippet de código aqui.
fonte
No meu caso (mesma mensagem de erro), estou desenvolvendo uma estratégia customizada e não preciso usar sessão . Eu apenas esqueci de adicionar
session: false
no meuauthenticate
middleware de rota .fonte