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

时间:2013-05-27 22:25:34

标签: node.js express mongoose restful-authentication passport.js

我正在使用express + mongoose的节点,并试图将passport.js与restful api一起使用 身份验证成功后我一直收到此异常(我在浏览器上看到了回调网址):

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

8 个答案:

答案 0 :(得分:179)

按照示例来避免表达的无序中间件地狱让它变得如此容易进入。直接来自文档。请注意你的内容与此完全不符。

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

答案 1 :(得分:9)

在我的情况下(相同的错误消息)我忘了添加护照初始化:

postmap /etc/postifx/access

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

答案 2 :(得分:7)

在我的情况下,错误是因为我试图宣传req.login而没有将this绑定到req,所以当调用该函数时,它无法找到passport设置。 如果您使用的是Node v8,该解决方案会在将req.login.bind(req)传递给promisify之前进行绑定。

答案 3 :(得分:2)

Peter Lyons的回答帮我解决了,但我用不同的方式解决了它。

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

请查看我的GitHub repo了解整个代码,而不仅仅是这里的代码段。

答案 4 :(得分:0)

对我有帮助的还在于在 cookies 配置之后放置路由

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

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

app.use(passport.initialize())中间件放在app.router中间件的前面,它的工作原理就像一个魅力

答案 7 :(得分:0)

你所要做的就是把这个代码放在你这样使用的路由器之前

class Speaker: Service() {
override fun onCreate() {
    super.onCreate()
    
    mTextToSpeech = TextToSpeech(applicationContext) { status ->
        if (status == TextToSpeech.SUCCESS) {
            Locale("en_IN").also {
                mTextToSpeech?.language = it
                initialized = true
            }
        }
    }
}

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {

    val dataToSpeak = intent?.getStringExtra(NotificationService.NOTIFICATION_EXTRA)
    
    dataToSpeak?.let {
        mTextToSpeech?.speak(dataToSpeak, TextToSpeech.QUEUE_ADD, null, dataToSpeak.hashCode().toString())
    }
    return START_REDELIVER_INTENT
}

override fun onBind(intent: Intent?): IBinder? = null

override fun onDestroy() {
    super.onDestroy()
    
    if (initialized) {
        mTextToSpeech?.shutdown()
        mTextToSpeech = null
    }
}

companion object {
    private var mTextToSpeech: TextToSpeech? = null
    private var initialized: Boolean = false
}