我正在使用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'
});
});
});
};
答案 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 :(得分: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
}