不使用的中间件

我使用的是 Express + monose 的 node,并尝试使用 restful api 的 passport.js。
I keep getting this exception after authentication success (I see the callback url on the browser):

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

怎么了?

UPDATE 根据@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'
});
});
});
};
90044 次浏览

按照这个示例可以避免无序的中间件,因为 Express 使得输入起来非常容易。直接从医生那里拿的。注意你的和这个完全不匹配。

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. 护照,会议
  5. app.router

  1. Passport.initialize
  2. 护照,会议
  3. CookieParser
  4. 会议
  5. 应用程序路由器

在我的例子中(同样的错误消息) ,我完全忘了添加护照初始化:

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

更新: 只升级到快速版本3,版本4不再支持 app.configure ()

Peter Lyons 的回答帮助我解决了这个问题,但是我用不同的方法解决了。

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

看看我的 GitHub 回收站代码,不仅仅是这里的代码片段。

在我的例子中,错误是因为我试图保证 req.login不绑定 thisreq,所以当函数被调用时,它无法找到 passport设置。 如果使用 Node v8,解决方案是在将 req.login.bind(req)传递给 promisify之前绑定 req.login.bind(req)

还帮助我把 路线放在 饼干配置之后:

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

在我的案例中(相同的错误消息) ,我正在开发一个自定义策略和 I 不需要使用会话。我只是忘记在路由 authenticate中间件中添加 session: false

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

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

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

app.use('/users', usersRouter);//this is the router  I am using


//and this is the code you have to copy


app.use(passport.initialize());
app.use(passport.session());