83

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

我正在使用 Passport 使用 Instagram 进行身份验证。验证成功后,用户被定向到“/”。此时,请求具有用户对象(又名它正在工作)。但是,一旦我重定向, 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
}
4

26 回答 26

68

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

fetch('/api/foo', {credentials: 'include'})
于 2016-12-24T20:34:37.707 回答
51

您是否为您的应用设置了会话状态?如果你还没有,你需要这样的东西......

app.use(session({ secret: 'anything' }));
app.use(passport.initialize());
app.use(passport.session());
于 2013-05-08T12:13:31.770 回答
19

我对 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);

希望这可以帮助

于 2014-03-20T05:56:47.250 回答
13

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

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

现在它可以工作了。

于 2016-03-13T12:16:05.533 回答
7

我遇到了同样的问题,因为只是从 express-session 文档中复制并粘贴以下代码,但没有完全阅读文档。

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

在文档中,它提到:

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

因此,如果您只有一个 HTTP 连接,请删除安全选项,下面的代码应该可以工作:

app.use(session({
  secret: 'keyboard cat',
  resave: false,
  saveUninitialized: true,
  //cookie: { secure: true } remove this line for HTTP connection
}))
于 2017-06-13T12:16:58.230 回答
4

是的,启用像@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'}))

有关更多信息,请查看快速会话文档。

于 2014-06-18T13:55:53.657 回答
4

我在使用 express 4 时遇到了同样的问题,在尝试了几乎所有我能在网上找到的东西之后,我终于设法通过添加“cookie-session”来让它工作。

var cookieSession = require('cookie-session');

app.use(cookieSession({
  keys: ['key1', 'key2']
}));
于 2015-02-14T10:27:20.600 回答
4

我认为每个人在服务器端都有几个可能导致这个问题的错误。

要解决此错误,请检查以下内容:

检查 1 - Passport 序列化和反序列化

正确的做法(猫鼬):

passport.serializeUser((user, done) => {
    done(null, user._id);
});

passport.deserializeUser((_id, done) => {
  User.findById( _id, (err, user) => {
    if(err){
        done(null, false, {error:err});
    } else {
        done(null, user);
    }
  });
});

检查 2 - 会话

检查您的cookie-session包是否配置正确且正常工作。检查您是否真的可以在客户端看到 cookie。如果您使用的是express-session,请确保您可以在内存或缓存(Redis)中看到 session-id。

检查 3 - SSL nginx

确保您的反向代理支持 cookie 和请求类型。不要忘记检查 cookie/会话配置 [secure标志]

当我遇到这个错误时,我正在使用(user)回调函数。然后我用(err, user). 现在没事了。干杯

于 2019-12-30T09:11:39.877 回答
3

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

app.get('/auto-login', passport.authenticate('cross', {session: true}))
于 2013-10-16T19:27:03.210 回答
3

当您对用户进行身份验证时,req.user会填充请求值。要知道是否识别用户并填写该值,使用 cookie。如果像我一样,您使用安全 cookie 配置会话,cookie 将仅在 上可用HTTPS,这不是本地开发服务器的标准配置。要让 cookie 正常工作HTTP,注释掉cookie: { secure: true }req.user正确配置值:

this.app.use(session({
    resave: true,
    saveUninitialized: true,
    secret: process.env.SESSION_SECRET || "a secret",
    // cookie: { secure: true },
}));

如果合理地,您HTTPS只希望在生产中使用 cookie,您可以执行以下操作:

cookie: { secure: process.env.ENV === 'PRODUCTION' }
于 2019-02-07T16:06:12.227 回答
1

我的是关于饼干和软糖的。我通过将以下代码添加到我的服务器来解决:

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();
}};
于 2016-01-25T22:33:06.020 回答
1

设置快速会话后,请确保在生成 req.user 的反序列化函数中具有护照序列化和反序列化。请参阅另一个 stackoverflow问题的解释。

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


passport.deserializeUser(function(user, done) {
 done(null, user);
});
于 2017-10-09T16:03:59.240 回答
1

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

this._http.get("endpoint/something", { withCredentials: true })
于 2017-11-05T11:55:25.630 回答
1

这样做passport.authenticate时,您可以添加session: true以解决您的问题:

app.post("/login", passport.authenticate('local', {
    'failureRedirect': '/login',
    'session': true
}), (req, res)=>{ res.redirect("/"); });
于 2018-11-24T19:12:24.993 回答
1

我的与所有这些不同。我之前一直在 localhost 上开发一个 Wordpress 站点,然后切换到一个单独的 Node/React 项目。

来自 Wordpress 站点的 cookie 仍然存在并被发送,因为这两个项目都在 localhost 上运行。这导致了这个问题。

我必须清除 localhost 的 cookie,然后它才起作用。

于 2018-12-20T00:24:38.410 回答
1

服务器发送 SetCookie 标头,然后浏览器句柄来存储它,然后 cookie 与在 Cookie HTTP 标头内向同一服务器发出的请求一起发送。

我必须在我的客户端中设置 withCredentials: true 。(axios.js)

const config = {
  withCredentials: true,
  headers: {
    'Content-Type': 'application/json',
  },
};

axios.put(url, { page: '123' }, config)
  .then(res => console.log('axios', res))
  .catch(err => console.log('axios', err));

然后出现CORS问题。

所以我将它添加到我的快递服务器:

app.use(function(req, res, next) {
  res.header('Access-Control-Allow-Credentials', true);
  res.header('Access-Control-Allow-Origin', req.headers.origin);
  res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
  res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
  if ('OPTIONS' == req.method) {
    res.send(200);
  } else {
      next();
  }
});
于 2019-05-21T21:00:53.710 回答
1

只有在 passport.auth 中间件之后,我才将“req.user”设置为用户。我来到这个线程试图找出如何从其他请求访问用户名(没有passport.auth中间件),如果其他人被困在这个问题上,那么试试

req._passport.session.user;
于 2021-06-25T09:47:18.960 回答
0

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

if (req.user) {
    req.session.save(function (err) {
        if (err) {
            // ... panic!
        }
        res.redirect("/user/" + req.user._id);
    });
    return;
}
于 2014-09-05T00:45:35.150 回答
0

您是否尝试在 cookieParser 中插入您的密钥?

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());
于 2015-08-12T14:00:37.383 回答
0

有完全相同的问题。对我来说,解决方案是使用“client-sessions”而不是“express-session”。可能是错误的会话配置?

不工作的代码:

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,
    }));
于 2016-09-29T16:53:54.460 回答
0

我遇到了同样的问题,req.isAuthenticated() 和 req.user,这就是我的解决方法

  • req.isAuthenticated() 通过在 deserialize() 中的 findById() 方法中用 find() 替换 findOne() 来解决,然后我可以保存经过身份验证的 req,否则它什么也不返回。

  • req.user 通过调整顺序解决,首先应该存储 express-session,然后应该初始化护照,然后在 passport.session() 中存储下一个会话,然后我们可以访问 req.user,在将会话保存在 passport.session() 中之后

app.use(session(...));
app.use(passport.initialize());
app.use(passport.session());
// Now we can access req.user so after we will call req.user, if we write it above these, it will always return underfined
app.use(function(req, res, next){
  res.locals.user = req.user || null
  next();
})

看,如果你在之后访问 req.user passport.session(),如果没有在下面添加你的路由。

于 2018-07-18T09:48:22.417 回答
0

我的两分钱:不工作的代码:

server.use(
session({
  secret: "secretsssss",
  rolling: false,
  resave: false,
  saveUninitialized: false,
  cookie: {
    sameSite: true, //this line
    maxAge: 60 * 60 * 1000
  }
})
);

工作代码:

server.use(
session({
  secret: "secretsssss",
  rolling: false,
  resave: false,
  saveUninitialized: false,
  cookie: {
    sameSite: false, // i think this is default to false
    maxAge: 60 * 60 * 1000
  }
})
);
于 2019-01-26T02:30:29.023 回答
0

遇到了同样的问题,但是我的问题更多与对 OAuth 流程和 OAuth 回调路由之间的区别的误解passport.authorize有关passport.authenticate

passport.authorize不会影响req.user变量,但是由于我只是从策略文档中复制粘贴了示例代码,因此我没有意识到使用了错误的方法。更改为passport.authenticate用户变量后可用。

希望这可以帮助任何可能在不知不觉中做同样事情的人。

于 2020-03-01T23:36:33.613 回答
0

从此更改顺序:

app.set("view engine", "ejs");
app.use(bodyParser.urlencoded({ extended: true }));

对此:

app.use(bodyParser.urlencoded({ extended: true }));
app.set("view engine", "ejs");
于 2020-08-02T05:06:35.870 回答
0

我正在使用 cookie-parser 和 express-session ,如下所示:

var express = require("express"); // 4.16.1
var cors = require("cors"); // 2.8.5
var cookieParser = require("cookie-parser"); // 1.4.4
var expressSession = require("express-session"); // 1.17.1

var app = express();

app.use(
  cors({
    origin: "http://localhost:3000",
    credentials: true,
  })
);

app.use(express.json());
app.use(express.urlencoded({ extended: true }));


app.use(
  expressSession({
    secret: "secret123",
    resave: true,
    saveUninitialized: true,
    cookie: { maxAge: 60 * 60 * 24 * 1000 },
  })
);
app.use(cookieParser("secret123")); // this line

在 express-session 之前放置 cookie-parser 对我有用,如下所示:

var express = require("express"); // 4.16.1
var cors = require("cors"); // 2.8.5
var cookieParser = require("cookie-parser"); // 1.4.4
var expressSession = require("express-session"); // 1.17.1

var app = express();

app.use(
  cors({
    origin: "http://localhost:3000",
    credentials: true,
  })
);

app.use(express.json());
app.use(express.urlencoded({ extended: true }));

app.use(cookieParser("secret123"));
app.use(
  expressSession({
    secret: "secret123",
    resave: true,
    saveUninitialized: true,
    cookie: { maxAge: 60 * 60 * 24 * 1000 },
  })
);
于 2020-11-16T18:39:27.180 回答
-1

我有一个不同的问题,与 bcrpt-node 和箭头函数有关。

有效的代码:

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);
};
于 2016-06-04T12:06:00.090 回答