首页 > 解决方案 > Req.user 在 POST 和 GET 之间丢失

问题描述

我是 Node 新手,从Rocket Rides 演示开始。试点注册适用于网络应用程序,我想为网络上的乘客做同样的事情(而演示在 iOS 上有乘客注册)。我不明白为什么req.user使用飞行员的原始代码而不是我对乘客的修改来维护。

console.log()在 GET 中添加server/routes/pilots/pilots.js

/**
 * GET /pilots/signup
 *
 * Display the signup form on the right step depending on the current completion.
 */
router.get('/signup', (req, res) => {
  let step = 'account';
  console.log("*** Req.user = " + req.user);
  // ...
});

并在 POST 中:

/**
 * POST /pilots/signup
 *
 * Create a user and update profile information during the pilot onboarding process.
 */
router.post('/signup', async (req, res, next) => {
  const body = Object.assign({}, req.body, {
    // Use `type` instead of `pilot-type` for saving to the DB.
    type: req.body['pilot-type'],
    'pilot-type': undefined,
  });

  // Check if we have a logged-in pilot
  let pilot = req.user;
  if (!pilot) {
    try {
      // Try to create and save a new pilot
      pilot = new Pilot(body);
      pilot = await pilot.save()
      // Sign in and redirect to continue the signup process
      req.logIn(pilot, err => {
        if (err) next(err);
        console.log("About to redirect with:");
        console.log(pilot);
        return res.redirect('/pilots/signup');
      });
    } catch (err) {
      // Show an error message to the user
      const errors = Object.keys(err.errors).map(field => err.errors[field].message);
      res.render('pilot-signup', { step: 'account', error: errors[0] });
    }
  } 
  else {
    // ...
  }
});

乘客代码类似,我将其包含在底部。试点注册的服务器日志显示:

*** Req.user = 未定义
获取/飞行员/注册 200 136.726 毫秒 - 1865
获取 /stylesheets/rocketrides.css 304 0.911 毫秒 - -
获取 /javascripts/rocketrides.js 304 1.043 毫秒 - -
获取 /images/header.jpg 304 5.187 毫秒 - -
获取 /images/rocketrides.svg 304 10.075 毫秒 - -
即将重定向:
{
  火箭:{国家:'美国'},
  类型:'个人',
  国家:'美国',
  _id: 5e7e24d38794fa32032fd052,
  电子邮件:'name@example.com',
  密码: '...',
  创建时间:2020-03-27T16:07:47.054Z,
  __v: 0
}
POST /pilots/signup 302 116.113 毫秒 - 72
*** 请求用户 = {
  火箭:{国家:'美国'},
  类型:'个人',
  国家:'美国',
  _id: 5e7e24d38794fa32032fd052,
  电子邮件:'name@example.com',
  密码: '...',
  创建时间:2020-03-27T16:07:47.054Z,
  __v: 0
}
获取/飞行员/注册 200 93.455 毫秒 - 6018

我定制的乘客注册日志显示:

*** Req.user = 未定义
获取 /passengers/signup 200 165.900 毫秒 - 1869
获取 /stylesheets/rocketrides.css 304 2.573 毫秒 - -
获取 /javascripts/rocketrides.js 304 1.161 毫秒 - -
获取 /images/header.jpg 304 4.349 毫秒 - -
获取 /images/rocketrides.svg 304 4.423 毫秒 - -
即将重定向:
{
  火箭:{国家:'美国'},
  类型:'个人',
  _id: 5e7e259d8794fa32032fd053,
  电子邮件:'name@example.com',
  密码: '...',
  创建时间:2020-03-27T16:11:09.273Z,
  __v: 0
}
POST /passengers/signup 302 32.873 毫秒 - 80
*** Req.user = 未定义
获取 /passengers/signup 200 137.442 毫秒 - 1869

在这两种情况下都req.user以 开头undefined,然后将用户(乘客或飞行员)保存到数据库中,并且代码使用有效对象重定向到 GET。对于 Pilot,该对象由 GET 请求接收,但不适用于乘客。

该应用程序已经使用状态会话app.js并适用于一种类型的注册,所以我的问题与这个线程不同。对于大多数人来说,这可能是显而易见的,并且隐藏在新手的代码中。我还包括passport.serializeUser()frompilots.jspassengers.js.

我怎样才能解决这个问题,或者调试它?

附加功能

GET 的代码server/routes/passengers/passengers.js

/**
 * GET /passengers/signup
 *
 * Display the signup form on the right step depending on the current completion.
 */
router.get('/signup', (req, res) => {
  let step = 'account';
  console.log("*** Req.user = " + req.user);
  // ...
});

同一文件中 POST 的代码:

/**
 * POST /passengers/signup
 *
 * Create a user and update profile information during the passenger onboarding process.
 */
router.post('/signup', async (req, res, next) => {
  const body = Object.assign({}, req.body, {
    // Use `type` instead of `passenger-type` for saving to the DB.
    type: req.body['passenger-type'],
    'passenger-type': undefined,
  });

  // Check if we have a logged-in passenger
  let passenger = req.user;
  if (!passenger) {
    try {
      // Try to create and save a new passenger
      passenger = new Passenger(body);
      passenger = await passenger.save()

      // Sign in and redirect to continue the signup process
      req.logIn(passenger, err => {
        if (err) next(err);
        console.log("About to redirect with:");
        console.log(passenger);
        return res.redirect('/passengers/signup');
      });
    } catch (err) {
      // Show an error message to the user
      const errors = Object.keys(err.errors).map(field => err.errors[field].message);
      res.render('passenger-signup', { step: 'account', error: errors[0] });
    }
  } 
  else {
    // ...
  }
});

标签: javascriptnode.jsexpress

解决方案


没看懂Passport策略,把passport用户作为pilot被序列化和反序列化。只有第一个passport.serialize()函数有效;当我第一次导入时passengers.js,飞行员被序列化和反序列化为乘客。

请参阅这篇文章了解护照的工作原理(来自PassportJS serializeUser 和 deserializeUser 执行流程),以及有关如何通过单个序列化和反序列化处理多个本地策略的这个 Github 问题。

就我而言,我将使用user乘客和飞行员继承的类。


推荐阅读