节点+ Express + Passport:req.user未定义

我的问题与此类似,但对他的解决scheme没有深入的了解。

我正在使用Passport来validation使用Instagram。 成功validation后,用户被定向到“/”。 在这一点上,请求有用户对象(即它正在工作)。 但是,一旦我redirect,req.user是未定义的。 :'(

奇怪的是passport.deserializeUser正在被每个请求调用。 它成功地获取用户对象,但是在中间件的道路上,req.user没有被设置(或未被设置)。

// on successful auth, goto "/" app.get('/', function(req, res) { // if the request has the user object, go to the user page if (req.user) { res.redirect("/user/" + req.user._id); } res.render("index"); } app.get('/user/:uid', function(req, res) { console.log(req.user) // undefined } 

你有没有为你的应用设置会话状态? 你需要这样的东西…

 app.use(session({ secret: 'anything' })); app.use(passport.initialize()); app.use(passport.session()); 

我的问题是没有指定在客户端使用fetch时发送cookie。 它包含凭证后的工作:请求中的“包含”字段。

 fetch('/api/foo', {credentials: 'include'}) 

我对Node很新,但对我来说这是一个中间件问题。 添加bodyParser并重新安排修复。

破码:

 app.use(express.cookieParser('secret')); app.use(express.cookieSession()); app.use(express.session({ secret: 'anything' })); app.use(passport.initialize()); app.use(passport.session()); app.use(app.router); app.use(express.static(path.join(__dirname, 'public'))); 

工作代码:

 app.use(express.static(path.join(__dirname, 'public'))); app.use(express.cookieParser()); app.use(express.bodyParser()); app.use(express.session({ secret: 'anything' })); app.use(passport.initialize()); app.use(passport.session()); app.use(app.router); 

希望这可以帮助

以前我有这些代码(没有工作):

 app.use(express.static(path.join(__dirname, 'public'))); app.use(cookieParser('abcdefg')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: true})); app.use(session({ secret: 'abcdefg', resave: true, saveUninitialized: false, cookie: { secure: true } // this line })); app.use(passport.initialize()); app.use(passport.session()); app.use(require('stylus').middleware(path.join(__dirname, 'public'))); 

然后,我从会话初始化程序中删除cookie选项:

 app.use(express.static(path.join(__dirname, 'public'))); app.use(cookieParser('abcdefg')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: true})); app.use(session({ secret: 'abcdefg', resave: true, saveUninitialized: false })); app.use(passport.initialize()); app.use(passport.session()); app.use(require('stylus').middleware(path.join(__dirname, 'public'))); 

现在它工作。

在路由中,尝试添加: {session: true}

 app.get('/auto-login', passport.authenticate('cross', {session: true})) 

是的,启用像@Martin会议说。 但是,如果您使用的是Express 4. *版本,则会话等中间件不会捆绑在一起,因此您需要单独安装。

  1. 在package.json中添加“express-session”:“1.4.0”
  2. npm安装
  3. 用它

;

 var express = require('express'); var cookieParser = require('cookie-parser') var session = require('express-session') var app = express() app.use(cookieParser()) // required before session. app.use(session({secret: 'keyboard cat'})) 

欲了解更多信息,请查看快递会议文件。

我有这个完全相同的问题,使用快递4,并尝试几乎所有我可以在网上find我终于成功地通过添加“cookie会话”得到它的工作。

 var cookieSession = require('cookie-session'); app.use(cookieSession({ keys: ['key1', 'key2'] })); 

我遇到同样的问题,因为只是复制和粘贴以下快速会话文档中的代码,但没有完整阅读文档。

 app.use(session({ secret: 'keyboard cat', resave: false, saveUninitialized: true, cookie: { secure: true } })) 

在文件中提到:

但是,它需要启用https的网站,即HTTPS对于安全cookie是必需的。 如果设置了安全性,并且您通过HTTP访问您的站点,则Cookie不会被设置。

所以如果你只有一个HTTP连接,删除安全选项,下面的代码应该工作:

 app.use(session({ secret: 'keyboard cat', resave: false, saveUninitialized: true, //cookie: { secure: true } remove this line for HTTP connection })) 

如果您的中间件堆栈不清楚,假设您有会话中间件,您可以在redirect之前保存会话:

 if (req.user) { req.session.save(function (err) { if (err) { // ... panic! } res.redirect("/user/" + req.user._id); }); return; } 

你有没有尝试在cookieParser中插入你的secretKey?

 var passport = require('passport'); var expressSession = require('express-session'); app.use(express.static(path.join(__dirname, 'public'))); app.use(cookieParser('mySecretKey')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use(expressSession({ secret: 'mySecretKey', resave: false, saveUninitialized: true })); app.use(passport.initialize()); app.use(passport.session()); 

我的是关于cookies和cors。 我解决了通过添加以下代码到我的服务器:

 allowCrossDomain = function(req, res, next) { res.header('Access-Control-Allow-Origin', 'http://localhost:3000'); // your website res.header('Access-Control-Allow-Credentials', 'true'); res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS'); res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With'); if ('OPTIONS' === req.method) { res.send(200); } else { next(); }}; 

我有一个不同的问题,与bcrpt节点和箭头function。

代码工作:

 userSchema.methods.generateHash = function (password) { return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null); }; userSchema.methods.isValidPassword = function (password) { return bcrypt.compareSync(password, this.password); }; 

不起作用的代码:

 userSchema.methods.generateHash = (password) => { return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null); }; userSchema.methods.isValidPassword = (password) => { return bcrypt.compareSync(password, this.password); }; 

有完全一样的问题。 对我来说,解决scheme是使用“客户端会话”,而不是“快速会话”。可能是坏的会话configuration?

不工作的代码:

 var session = require('express-session'); app.use(bodyParser.urlencoded({ extended: false })); app.use(express.static(path.join(__dirname, 'public'))); app.use(cookieParser()); app.use(bodyParser.json()); app.use(session({ secret: 'random string', resave: true, saveUninitialized: true, cookie: { secure: true } })); 

工作代码:

 var session = require('client-sessions'); app.use(bodyParser.urlencoded({ extended: false })); app.use(express.static(path.join(__dirname, 'public'))); app.use(cookieParser()); app.use(bodyParser.json()); app.use(session({ cookieName: 'session', secret: 'random string', duration: 30 * 60 * 1000, activeDuration: 5 * 60 * 1000, })); 

一旦你有你的快速会话设置,请确保你有护照序列化和反序列化,在req.user生成时的反序列化函数。 从另一个stackoverflow问题看这里的解释。

 passport.serializeUser(function(user, done) { done(null, user); }); passport.deserializeUser(function(user, done) { done(null, user); }); 

当你在客户端使用http请求时,请记住要附加凭证。 在Angular2中,你需要添加选项参数:{withCredentials:true}。 在此之后,您将有相同的req.sessionID,直到您再次重置。

 this._http.get("endpoint/something", { withCredentials: true })