Passport.js Passport.initialize()中间件未使用


103

我正在将节点与express +猫鼬一起使用,并尝试通过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());app.use(passport.session());app.use(app.router);,这就是我所做的。这是我的express.js,用于注册中间件:

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

Answers:


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. 护照初始化
  4. 护照会议
  5. 应用路由器

  1. 护照初始化
  2. 护照会议
  3. cookieParser
  4. 会议
  5. 应用路由器

我已将其更改为您的建议,但仍会引发此错误。我用新的express.js文件更新了我的问题/
Naor

7
因此,这里的代码不是您的顶级代码。在你的程序早些时候,你在做任何电话app.getapp.post等?这些将导致路由器比您预期的早添加到堆栈中。向我们展示从调用express()函数获取app对象开始的所有启示代码。那是我的第二个猜测。
里昂

3
我注意到了app.use(app.router); 在护照初始化后被调用,但我打电话给:require('./ config / routes')(app,passport,auth); 在致电表达配置之前。两条线路之间的切换解决了该问题。谢谢!
瑙尔

1
这对我有用!但是,为什么中间件必须如此排序?
安东尼要

3
通过设计,您可以依赖已完成的先决条件。如果cookieParser尚未解析cookie,则会话将无法进行。
彼得·里昂斯

12

就我而言(相同的错误消息),我根本忘记添加护照初始化:

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

更新:仅适用于表达版本3,版本4不再支持app.configure()


1
无法再使用App.configure。github.com/strongloop/express/wiki/… ..他们应该更新护照文件。对?
杰克

9

在我的情况下,错误是因为我试图在req.login没有绑定this到的情况下进行承诺req,所以在调用函数时找不到passport设置。如果使用的是Node v8 req.login.bind(req)promisify则解决方案必须先绑定。


例如,当您使用诸如function({ login })传递reqas作为第一个参数的参数分解时,就会发生“范围问题” 。您的解决方案对我
有用

是的,这就是thisJavascript的工作方式。如果您不将函数作为对象方法调用,那么this它将是undefined(或window在浏览器中)
胡佳仪

给任何阅读此答案但不了解它的人的提示...如果您研究Function.prototype.callFunction.prototype.apply如何this使用Javascript以及原型继承的原理,您将在此过程中提升到Javascript Guru的水平:)
Stijn de Witt

干杯,我希望它会像util.promisify(req.login.bind(req));
朱利安·林

4

帮助我的还在于在cookie配置之后放置路由

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

知道为什么配置后初始化路由有效吗?
Ishu

这解决了我的问题。我移动了所有路线。在护照相关的物品之后使用电话。
尼克·范·布伦特

2

彼得·里昂斯(Peter Lyons)的回答帮助我解决了问题,但是我以不同的方式解决了它。

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

看看我的GitHub存储库中的整个代码,而不仅仅是这里的代码片段。


1

就我而言(相同的错误消息),我正在开发一种自定义策略,不需要使用session。我只是忘记添加session: false路由authenticate中间件。

  app.post('/api/public/auth/google-token',
    passport.authenticate('google-token', {
      session: false
    }),
    function (req: any, res) {
      res.send("hello");
    }
  );
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.