passport.js passport.initialize()ミドルウェアは使用されていません


103

私はexpress + mongooseでnodeを使用しており、restful apiでpassport.jsを使用しようとしています。
認証が成功した後もこの例外が発生し続けます(ブラウザーにコールバックURLが表示されます)。

/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

私は前に置くべきことを読んだことがapp.use(passport.initialize());あり、これは私がやったことです。これがミドルウェアを登録する私のexpress.jsです:app.use(passport.session());app.use(app.router);

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

なにが問題ですか?

更新 @Peter Lyonsによると、設定の順序を次のように変更しましたが、同じエラーが発生します。

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バージョンは、いくつかのメソッドをサポートしていません。github.com/strongloop/express/wiki/Migrating-from-3.x-to-4.xを
miksiii

回答:


206

例に従うことで、表現が乱れるミドルウェアの地獄を避け、簡単に入力できるようになります。ドキュメントから直接。あなたの方法がこれと正確に一致しないことに注意してください。

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());

文書

  1. cookieParser
  2. セッション
  3. passport.initialize
  4. passport.session
  5. app.router

君は

  1. passport.initialize
  2. passport.session
  3. cookieParser
  4. セッション
  5. app.router

私はそれをあなたが提案するものに変更しましたが、それでもこのエラーがスローされます。新しいexpress.jsファイルで質問を更新しました/
Naor

7
したがって、ここにあるコードはトップレベルのコードではありません。以前のプログラムであなたはへの呼び出しを行っているapp.getapp.postなど?これにより、ルーターが予定よりも早くスタックに追加されます。オブジェクトexpress()を取得する関数を呼び出すときから始まる、関連するすべてのコードを示しappます。それは私の2番目の推測です。
Peter Lyons 2013年

3
app.use(app.router);に気づきました。パスポートの初期化後に呼び出されますが、私は呼び出します:require( './ config / routes')(app、passport、auth); 構成を呼び出す前に。両方の回線を切り替えることで問題は解決しました。ありがとう!
Naor 2013年

1
これは私のために働いた!しかし、なぜミドルウェアはそのようにする必要があるのでしょうか?
Anthonyが

3
設計により、実行されている前提条件に依存できます。cookieParserがcookieをまだ解析していない場合、セッションは機能しません。
Peter Lyons 2014

12

私の場合(同じエラーメッセージ)、パスポートの初期化を追加するのを忘れていました。

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

更新:Expressバージョン3までのみ機能し、バージョン4はapp.configure()をサポートしなくなりました


1
App.configureは使用できなくなりました。github.com/strongloop/express/wiki/… ..パスポートドキュメントを更新する必要があります。正しい?
ジャックブランク

9

私はpromisifyしようとしていたので、私の場合はエラーとなったreq.login結合せずthisreq、その関数が呼び出されたときにそれを見つけることができませんでしたpassport設定を。Node v8を使用req.login.bind(req)しているpromisify場合は、ソリューションが渡される前にバインドされます。


そして、この「スコープの問題」は、たとえば最初の引数としてfunction({ login })渡すような構造化引数を使用するときに発生しreqます。あなたの解決策は私にとってうまく
いき

うん、それthisはJavascriptでどのように機能するかです。あなたがオブジェクトのメソッドとして関数を呼び出していない場合は、その後thisになりますundefined(またはwindowブラウザで)
嘉義胡

あなたが調査している場合、誰この回答を読んで、それを理解していないためのヒントは... Function.prototype.callFunction.prototype.apply、どのようにthisJavaScriptで動作し、プロトタイプ継承の原理、あなたは:)過程でJavascriptの教祖のレベルに推進していきます
Stijnデウィット

乾杯、私はそれが同じくらい簡単であることを望んでいましたutil.promisify(req.login.bind(req));
ジュリアンH.ラム

4

何が私にも置くことだった助けたルートを AFTER クッキーの設定:

// 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);

なぜ設定が機能した後、そのinitルートが機能するのでしょうか?
Ishu

これで問題が解決しました。私はすべてのroutes.use呼び出しをパスポート関連の後に移動しました。
Nick Van Brunt

2

ピーター・ライオンズの回答は私がそれを解決するのに役立ちましたが、私は少し異なる方法でそれを解決しました。

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

ここにあるコードスニペットだけでなく、コード全体の私のGitHubリポジトリをご覧ください。


1

私の場合(同じエラーメッセージ)、カスタム戦略を開発しており、セッションを使用する必要はありませんsession: falseルートauthenticateミドルウェアを追加するのを忘れました。

  app.post('/api/public/auth/google-token',
    passport.authenticate('google-token', {
      session: false
    }),
    function (req: any, res) {
      res.send("hello");
    }
  );
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.