节点 + Express + Passport:req.user 在 Postman 中有效,但为 undefined

3

我的问题与这个类似,那里的所有答案都没有帮助到我。

我正在使用Passport.js和本地策略(passport-local-mongoose)。 下面的中间件在Postman上运行正常,但每当我尝试从React客户端运行时就会失败。

exports.isLoggedIn = (req, res, next) => {
  console.log(req.user) // undefined with react, but works from postman
  if (req.isAuthenticated()) {
    return next();
  }
}

这是我的app.js文件:

require('./handlers/passport');
app.use(cors())
app.use(session({
  secret: process.env.SECRET,
  key: process.env.KEY,
  resave: true,
  saveUninitialized: true,
  store: new MongoStore({ mongooseConnection: mongoose.connection })
}));
app.use(passport.initialize());
app.use(passport.session());

handlers/passport.js:

const passport = require('passport');
const mongoose = require('mongoose');
const User = mongoose.model('User');

passport.use(User.createStrategy());

passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

user.js (模型):

...
userSchema.plugin(passportLocalMongoose, { usernameField: 'email' });

客户端代码:

const url = 'http://localhost:7777/users/<id>';
const config = {
  headers: {
    'Content-Type': 'application/json',
  },
};

axios.put(url, data, config)
  .then(res => console.log(res))
  .catch(err => console.log(err));

我有点不明白,passportLocal策略是否意味着我不能像我的示例那样同时使用API和客户端?谢谢:D

1
展示你在React应用中向服务器发送请求的代码。 - alexmac
与普通的 http 调用没有任何区别。我正在使用 axios.js,而没有发送任何头文件,我已经尝试过以下代码:const headers = { credentials: 'include' }; - Jean Bauer
1
我不确定你在客户端认证用户时如何处理令牌。因此,由于您正在使用axios,您需要明确设置请求授权,并将其包含在后续请求中。请参考这个链接 - Rowland
嘿@Rowland,我需要在我的授权头中设置什么?这是我第一次使用passport.js,我不知道应该将什么作为“token”存储。在成功的/login之后,我可以看到响应头中的“set-cookie:”属性,我可以通过document.cookie访问它,在随后的请求中将其发送到服务器也不起作用。 - Jean Bauer
1个回答

4

所以,经过一些时间我找到了答案:

服务器发送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问题。

所以我在我的express服务器中添加了以下内容:

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();
  }
});

你真是个救命恩人啊,我在这里卡了三个小时,谢谢你救了我。 - Sunny Sultan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接