Używam węzła z express + mongoose i próbuję użyć passport.js z restful api.
Ciągle otrzymuję ten wyjątek po pomyślnym uwierzytelnieniu (widzę adres zwrotny w przeglądarce):
/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
Przeczytałem, że powinienem umieścić app.use(passport.initialize());
i app.use(passport.session());
wcześniej app.use(app.router);
i to właśnie zrobiłem. Oto mój express.js, który rejestruje oprogramowanie pośrednie:
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'
});
});
});
};
Co jest nie tak?
AKTUALIZACJA Zgodnie z @Peter Lyons zmieniłem kolejność konfiguracji na następującą, ale nadal pojawia się ten sam błąd:
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'
});
});
});
};
Odpowiedzi:
Postępuj zgodnie z przykładem, aby uniknąć piekła oprogramowania pośredniczącego nieczynnego w kolejności, które Express sprawia, że tak łatwo jest wejść. Prosto z dokumentacji. Zwróć uwagę, że twój nie pasuje do tego dokładnie.
Dokumenty
ty
źródło
app.get
,app.post
itp? To spowoduje, że router zostanie dodany do stosu wcześniej, niż zamierzasz. Pokaż nam WSZYSTKO rewelacyjny kod zaczynający się od wywołaniaexpress()
funkcji w celu uzyskaniaapp
obiektu. To moje drugie przypuszczenie.W moim przypadku (ten sam komunikat o błędzie) w ogóle zapomniałem dodać inicjalizacje paszportu:
AKTUALIZACJA: Działa tylko do wersji Express 3, wersja 4 nie obsługuje już app.configure ()
źródło
W moim przypadku błędu, ponieważ starałem się promisify
req.login
bez wiązaniathis
sięreq
, więc gdy funkcja została wywołana nie mógł znaleźćpassport
ustawienia. Rozwiązanie jest wiążącereq.login.bind(req)
przed przekazaniem go do,promisify
jeśli używasz Node v8.źródło
function({ login })
przekazaniereq
jako pierwszego argumentu. Twoje rozwiązanie zadziałało dla mnie, dziękithis
działa w Javascript. Jeśli nie wywołasz funkcji jako metody obiektowej,this
będzieundefined
(lubwindow
w przeglądarce)Function.prototype.call
,Function.prototype.apply
jakthis
działa JavaScript i zasady prototypowego dziedziczenia, awansujesz na poziom Javascript Guru :)util.promisify(req.login.bind(req));
Pomogło mi również umieszczenie tras PO konfiguracji plików cookie :
źródło
Odpowiedź Petera Lyonsa pomogła mi go rozwiązać, ale rozwiązałem go w nieco inny sposób.
Spójrz na moje repozytorium GitHub dla całego kodu, a nie tylko fragmentu kodu tutaj.
źródło
W moim przypadku (ten sam komunikat o błędzie), opracowywałem niestandardową strategię i nie potrzebuję sesji . Po prostu zapomniałem dodać oprogramowanie pośredniczące
session: false
trasauthenticate
.źródło
Umieść
app.use(passport.initialize())
oprogramowanie pośrednie przed produktem pośrednimapp.router
i działa jak urokźródło