passport.js passport.initialize () ara yazılım kullanımda değil


104

Express + mongoose ile node kullanıyorum ve passport.js'yi dinlendirici api ile kullanmaya çalışıyorum.
Kimlik doğrulama başarılı olduktan sonra bu istisnayı almaya devam ediyorum (tarayıcıda geri arama url'sini görüyorum):

/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

Ben koymak gerektiğini okudum app.use(passport.initialize());ve app.use(passport.session());daha önce app.use(app.router);ve bu benim yaptığım budur. İşte ara yazılımları kaydeden express.js'im:

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'
            });
        });
    });
};

Yanlış olan ne?

GÜNCELLEME @Peter Lyons'a göre yapılandırma sırasını şu şekilde değiştirdim, ancak yine de aynı hatayı alıyorum:

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'
            });
        });
    });
};

Express 4.x sürümleri bazı yöntemleri desteklemez. Bkz. Github.com/strongloop/express/wiki/Migrating-from-3.x-to-4.x
miksiii

Yanıtlar:


207

Express'in girmeyi çok kolaylaştıran sıra dışı ara yazılım cehenneminden kaçınmak için örneği izleyin. Doğrudan belgelerden. Sizinkinin buna tam olarak uymadığına dikkat edin.

var app = express();
app.use(require('serve-static')(__dirname + '/../../public'));
app.use(require('cookie-parser')());
app.use(require('body-parser').urlencoded({ extended: true }));
app.use(require('express-session')({
  secret: 'keyboard cat',
  resave: true,
  saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());

Dokümanlar

  1. cookieParser
  2. oturum, toplantı, celse
  3. passport.initialize
  4. passport.session
  5. app.router

Sen

  1. passport.initialize
  2. passport.session
  3. cookieParser
  4. oturum, toplantı, celse
  5. app.router

Önerdiğin şekilde değiştirdim ama yine de bu hatayı veriyor. Sorumu yeni express.js dosyasıyla güncelledim /
Naor

7
Yani burada sahip olduğunuz kod üst düzey kodunuz değil. Daha önce programınızda size herhangi bir çağrı yapıyoruz app.get, app.postvb? Bunlar, yönlendiricinin istediğinizden daha önce yığına eklenmesine neden olacaktır. Nesnenizi express()elde etmek için işlevi çalıştırdığınızda başlayan TÜM açığa çıkan kodu bize gösterin app. Bu benim ikinci tahminim.
Peter Lyons

3
App.use (app.router) olduğunu fark ettim; pasaport başlatıldıktan sonra çağrılır ama ben şunu çağırırım: gerekli ('./ config / route') (uygulama, pasaport, kimlik doğrulama); yapılandırmaları ifade etmeye çağırmadan önce. Her iki hat arasında geçiş yapmak sorunu çözdü. Teşekkürler!
Naor

1
Bu benim için çalıştı! Peki neden ara katman yazılımı bu şekilde sıralı olmak zorunda?
Anthony

3
Tasarım gereği, yapılan ön koşullara güvenebilirsiniz. CookieParser çerezleri henüz ayrıştırmadıysa oturum çalışmayacaktır.
Peter Lyons

12

Benim durumumda (aynı hata mesajı) Pasaport ilklendirmelerini eklemeyi hiç unuttum:

app.configure(function () {
    ...
    app.use(passport.initialize());
    app.use(passport.session());
});

GÜNCELLEME: Yalnızca sürüm 3'ü ifade etmek için çalışıyor, sürüm 4 artık app.configure () öğesini desteklemiyor


1
App.configure artık kullanılamaz. github.com/strongloop/express/wiki/… .. Pasaport belgelerini güncellemelidirler. sağ?
jack boş

9

Benim durumumda hata, req.loginbağlanmadan thissöz vermeye çalıştığım için oldu req, bu nedenle işlev çağrıldığında passportayarları bulamadı . Node v8 kullanıyorsanız çözüm, req.login.bind(req)ona geçmeden önce promisifybağlanıyor.


Ve bu "kapsam sorunu", örneğin ilk argüman olarak function({ login })geçmek gibi yıkıcı reqargümanlar kullandığınızda ortaya çıkar. Çözümünüz benim için çalıştı, teşekkürler
Manuel Di Iorio

Evet this, Javascript'te böyle çalışıyor. İşlevi nesne yöntemi olarak çağırmazsanız, o thiszaman olacaktır undefined(veya windowtarayıcıda)
Jiayi Hu,

Bu yanıtı okuyan ve anlamayanlar için ipucu ... Javascript'te nasıl çalıştığını ve prototip kalıtımın arkasındaki ilkeleri araştırırsanız Function.prototype.call, bu süreçte Javascript Guru seviyesine yükseleceksiniz :)Function.prototype.applythis
Stijn de Witt

Şerefe, bu kadar basit olmasını umuyordumutil.promisify(req.login.bind(req));
Julian H. Lam

4

Bana yardımcı olan şey ayrıca çerez yapılandırmasından SONRA rotalar koymaktı :

// init Cookies:
app.use(
    cookieSession({
        maxAge: 30 * 24 * 60 * 60 * 1000,
        keys: [keys.cookieKey]
    })
);
app.use(passport.initialize());
app.use(passport.session());

// init routes
const authRoutes = require("./routes/authRoutes")(app);

Konfigürasyondan sonra yolların neden çalıştığı hakkında bir fikriniz var mı?
Ishu

Bu benim sorunumu çözdü. Pasaportla ilgili herhangi bir şeyden sonra tüm rotaları taşıdım.
Nick Van Brunt

2

Peter Lyons'un cevabı çözmeme yardımcı oldu, ama ben onu farklı bir şekilde çözdüm.

app.use(
  cookieSession({
    maxAge: 30 * 24 * 60 * 60 * 1000,
    keys: [keys.cookieKey],
  }),
);
app.use(passport.initialize());
app.use(passport.session());

GitHub depoma sadece kod parçacığı için değil, kodun tamamı için bakın .


1

Benim durumumda (aynı hata mesajı), özel bir strateji geliştiriyordum ve bir oturum kullanmama gerek yok . Sadece session: falserota authenticateara yazılımımı eklemeyi unuttum .

  app.post('/api/public/auth/google-token',
    passport.authenticate('google-token', {
      session: false
    }),
    function (req: any, res) {
      res.send("hello");
    }
  );

0

Ara app.use(passport.initialize())katman yazılımını app.routerorta malın önüne yerleştirin ve bir cazibe gibi çalışır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.