Node + Express + Passport:req.user未定义

goj*_*ygo 63 node.js express passport.js

我的问题是类似这样的一个,但没有深入了解他的解决方案.

我正在使用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
}
Run Code Online (Sandbox Code Playgroud)

小智 49

我的问题是没有指定在客户端使用fetch时发送cookie.它包含了凭证:请求中的"包含"字段.

fetch('/api/foo', {credentials: 'include'})
Run Code Online (Sandbox Code Playgroud)

  • 花了太多时间寻找解决方案,尝试在服务器端以各种方式配置护照,只发现问题出在客户端代码中.感谢您的回答. (8认同)
  • 等等,这个小费怎么不容易找到?在找到之前,我阅读了很多StackOverflow问题和答案.谢谢你,Jon Rodness.谢谢. (4认同)
  • 扩展一下,只有当请求来自同一来源时,才会默认发送像 cookie 这样的内容。否则,您必须使用“withCredentials”标志来指定您确实希望发回 cookie。请参阅 https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials。请注意,如果您使用 Axios 之类的东西而不是 fetch API,语法将会有所不同。 (2认同)

Mar*_*tin 41

您是否为应用设置了会话状态?你需要这样的东西......

app.use(session({ secret: 'anything' }));
app.use(passport.initialize());
app.use(passport.session());
Run Code Online (Sandbox Code Playgroud)

  • 我完成了你所写的内容,我也收到了'undefined`消息. (17认同)
  • 认为这实际上是`app.use(session({secret:'anything'});`现在express-session是它自己的包而不是express的一部分 (3认同)
  • 这个解决方案对我有用,因为我的应用程序配置顺序错误。当我按照上面的顺序放置它们时,问题就解决了。 (3认同)
  • 设置表达式后我仍然遇到问题.我在初始化快速会话后调用护照功能,我可以在应用程序中使用没有问题的会话. (2认同)

小智 15

我是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'))); 
Run Code Online (Sandbox Code Playgroud)

工作守则:

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);
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助

  • 这对我有帮助。为什么中间件的第二个排序有效,而不是第一个? (2认同)

小智 8

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

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')));
Run Code Online (Sandbox Code Playgroud)

然后我从会话初始化程序中删除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')));
Run Code Online (Sandbox Code Playgroud)

现在它的工作原理.


ufx*_*eng 7

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

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

在文档中,它提到:

但是,它需要启用 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
}))
Run Code Online (Sandbox Code Playgroud)


Smi*_*tel 6

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

要解决此错误,请检查以下事项:

检查 1 - 护照序列化和反序列化

正确的做法(猫鼬):

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);
    }
  });
});
Run Code Online (Sandbox Code Playgroud)

检查 2 - 会话

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

检查 3 - SSL nginx

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

当我遇到这个错误时,我正在使用(user)回调函数。然后我用 纠正了它(err, user)。现在一切都好了。干杯