0

我在登录时使用用户登录,并且用户对象被保存为 req.user (或护照用户),但是在我转到不同的路线/状态后,它不再将用户对象保存在那里。为了演示,我只是尝试 console.log(req.user) 并返回未定义的,用于我的控制器中的 POST 方法(updateUserProfile)。我使用 PostMan 来测试 POST 方法,GET 方法在 Postman 上用于抓取所有用户。如果我刷新页面 app.get(*) 将加载 req.user 并打印它,它只是在调用中。可能是什么原因?这可能是我的快速设置吗?例子:

我的路线:

/**
 * Routes for express app
 */
var express = require('express');
var users = require('../controllers/users');
var feedback = require("../controllers/feedbackapi");
var problem = require("../controllers/problemapi");
var pair = require("../controllers/userproblempairapi");
var mongoose = require('mongoose');
var _ = require('lodash');
var Header = require('../../public/assets/header.server');
var App = require('../../public/assets/app.server');

module.exports = function(app, passport) {
  // user routes
  app.post('/login', users.postLogin);  
  app.post('/signup', users.postSignUp);
  app.get('/logout', users.getLogout);
  app.post('/updateUserProfile', users.updateUserProfile);

  // google auth
  // Redirect the user to Google for authentication. When complete, Google
  // will redirect the user back to the application at
  // /auth/google/return
  // Authentication with google requires an additional scope param, for more info go 
  // here https://developers.google.com/identity/protocols/OpenIDConnect#scope-param
  app.get('/auth/google', passport.authenticate('google', { scope: [
        'https://www.googleapis.com/auth/userinfo.profile',
        'https://www.googleapis.com/auth/userinfo.email'
      ] }));

  // Google will redirect the user to this URL after authentication. Finish the
  // process by verifying the assertion. If valid, the user will be logged in.
  // Otherwise, the authentication has failed.
  app.get('/auth/google/callback',
    passport.authenticate('google', {
      successRedirect: '/',
      failureRedirect: '/login'
    }));


   //Important** on refresh we look at our wildcard call to find out if we're still logged in.
  // Retrieves all topics on any endpoint for demonstration purposes
  // If you were indeed doing this in production, you should instead only
  // query the Topics on a page that has topics
  app.get('*', function(req, res, next) {


        // We don't want to be seeding and generating markup with user information
        var user = req.user ? { authenticated: true, isWaiting: false } : { authenticated: false, isWaiting: false };
        // An object that contains response local variables scoped to the request, and therefore available only to the view(s) rendered during
        // that request/response cycle (if any). Otherwise, this property is identical to app.locals
        // This property is useful for exposing request-level information such as request path name, authenticated user, user settings, and so on.
        // pass in data to be seeded into the TopicStore
        res.locals.data =  {
          UserStore: { user: user }
        };
        next();

  });

  // This is where the magic happens. We take the locals data we have already
  // fetched and seed our stores with data.
  // App is a function that requires store data and url to initialize and return the React-rendered html string
  app.get('*', function (req, res, next) {
    var html = App(JSON.stringify(res.locals.data || {}), req, res);
    html = html.replace("TITLE", Header.title)
                .replace("META", Header.meta);

    if(process.env.NODE_ENV === 'devhotloader') {
      html = html.replace("LINK", '');
    } else {
      html = html.replace("LINK", Header.link);
    }

    res.contentType = "text/html; charset=utf8";
    res.end(html);
  });

};;

我的用户控制器:

var _ = require('lodash');
var User = require('../models/user');
var passport = require('passport');
var ParsonsProblem = require('../models/parsonsproblem');
var Feedback = require('../models/feedback');
var UserProblemPair = require('../models/userproblempair');

/**
 * POST /login
 */
exports.postLogin = function(req, res, next) {

  // Do email and password validation for the server
  /*var Feed = new Feedback({
    description: 'Supsuop'
  });
  var Problem = new ParsonsProblem({
    description: 'Test',
    feedback: Feed
  });
  var Pair = new UserProblemPair({
    problem_id: Problem,
    attempt_quantity: 0,
    completed: true
  });
  */
  console.log(req.body);
  passport.authenticate('local', function(err, user, info) {
    if(err) return next(err);
    if(!user) {
      req.flash('errors', {msg: info.message});
    }
    // Passport exposes a login() function on req (also aliased as logIn()) that can be used to establish a login session
    req.logIn(user, function(err) {
      if(err) return next(err);
      req.flash('success', { msg: 'Success! You are logged in'});
      res.end('Success');
      console.log(req.user);
    });

  })(req, res, next);
  /*
  Feed.save(function(err) {console.log('Feedback saved');});
  Problem.save(function(err) {console.log('Problem saved');});
  Pair.save(function(err) {console.log('ProblemPair saved');});
  console.log(Feed);
  */
};

/**
 * POST UpdateUser Profile
 */
exports.updateUserProfile = function(req, res) {
      var id = req.user._id;
      if (req.body.firstName == "") {
        req.body.firstName = req.user.profile.firstName;
      }
      if (req.body.lastName == "") {
        req.body.lastName = req.user.profile.lastName;
      }
      if (req.body.gender == "") {
        req.body.gender = req.user.profile.gender;
      }
      if (req.body.section == "") {
        req.body.section = req.user.profile.section;
      }

      User.findById(id, function(err, user) {
        console.log("ID: " + id);
        user.profile.firstName = req.body.firstName;
        user.profile.lastName = req.body.lastName;
        user.profile.gender = req.body.gender;
        user.profile.section = req.body.section;
        user.save();
        res.end();
      });
}

/**
 * GET /logout
 */
exports.getLogout = function(req, res, next) {
  // Do email and password validation for the server
  console.log("User has been logged out");
  req.logout();
  res.redirect('/');
  //res.end():
};

/**
 * POST /signup
 * Create a new local account
 */
exports.postSignUp = function(req, res, next) {
  var user =  new User({
    email: req.body.email,
    password: req.body.password,
    profile: {
      firstName : req.body.firstName,
      lastName : req.body.lastName,
      section : req.body.section
    }
  });
  //user.profile.firstName = req.body.firstName;
  //user.profile.lastName = req.body.lastName;
  //user.profile.section = req.body.section;
  User.findOne({email: req.body.email}, function(err, existingUser) {
    if(existingUser) {
      req.flash('errors', { msg: 'Account with that email address already exists' });
      res.redirect('/sign');
    }
    user.save(function(err) {
      if(err) return next(err);
      req.logIn(user, function(err) {
        if(err) return next(err);
        console.log('Successfully created');
        console.log('Printing user');
        console.log(user);
        console.log('Print our body from our request');
        console.log(req.body);
        res.redirect('/');
      });
    });
  });
};

快速设置:

app.disable('x-powered-by');
  app.set('views', path.join(__dirname, '..', 'views'));

  app.set('view cache', false);

  app.use(bodyParser.json({limit: '100mb'}));
  app.use(bodyParser.urlencoded({extended: true})); // for parsing application/x-www-form-urlencoded
  app.use(methodOverride());
  app.use(express.static(path.join(__dirname, '../..', 'public')));

  // I am adding this here so that the Heroku deploy will work
  // Indicates the app is behind a front-facing proxy,
  // and to use the X-Forwarded-* headers to determine the connection and the IP address of the client.
  // NOTE: X-Forwarded-* headers are easily spoofed and the detected IP addresses are unreliable.
  // trust proxy is disabled by default.
  // When enabled, Express attempts to determine the IP address of the client connected through the front-facing proxy, or series of proxies.
  // The req.ips property, then, contains an array of IP addresses the client is connected through.
  // To enable it, use the values described in the trust proxy options table.
  // The trust proxy setting is implemented using the proxy-addr package. For more information, see its documentation.
  app.enable('trust proxy');
  // Cookie parser should be above session
  // cookieParser - Parse Cookie header and populate req.cookies with an object keyed by cookie names
  // Optionally you may enable signed cookie support by passing a secret string, which assigns req.secret
  // so it may be used by other middleware
  app.use(cookieParser());
  // Create a session middleware with the given options
  // Note session data is not saved in the cookie itself, just the session ID. Session data is stored server-side.
  // Options: resave: forces the session to be saved back to the session store, even if the session was never
  //                  modified during the request. Depending on your store this may be necessary, but it can also
  //                  create race conditions where a client has two parallel requests to your server and changes made
  //                  to the session in one request may get overwritten when the other request ends, even if it made no
  //                  changes(this behavior also depends on what store you're using).
  //          saveUnitialized: Forces a session that is uninitialized to be saved to the store. A session is uninitialized when
  //                  it is new but not modified. Choosing false is useful for implementing login sessions, reducing server storage
  //                  usage, or complying with laws that require permission before setting a cookie. Choosing false will also help with
  //                  race conditions where a client makes multiple parallel requests without a session
  //          secret: This is the secret used to sign the session ID cookie.
  //          name: The name of the session ID cookie to set in the response (and read from in the request).
  //          cookie: Please note that secure: true is a recommended option.
  //                  However, it requires an https-enabled website, i.e., HTTPS is necessary for secure cookies.
  //                  If secure is set, and you access your site over HTTP, the cookie will not be set.
  var sess = {
    resave: true,
    saveUninitialized: true,
    // Use generic cookie name for security purposes
    key: 'sessionId',
    secret: secrets.sessionSecret,
    // Add HTTPOnly, Secure attributes on Session Cookie
    // If secure is set, and you access your site over HTTP, the cookie will not be set
    cookie: {
      expires: false,
      httpOnly: false,
      //secure: false
    },
    store: new MongoStore({ url: secrets.db, autoReconnect: true})
  };

  var node_env = process.env.NODE_ENV;
  console.log('Environment: ' + node_env);
  //if(node_env === 'production') {
    //sess.cookie.secure = false; // Serve secure cookies
  //}

  app.use(session(sess));

  app.use(passport.initialize());
  app.use(passport.session());

  app.use(flash());

编辑:打印出 req.session 和 req.user 仅在登录和登录/注销时显示,当使用 react-router 转换到另一个视图时,它不再具有该信息。(“尝试使用控制台日志”)

4

1 回答 1

0

我认为您必须使用react-router来处理内部重定向。

于 2015-10-13T04:32:25.720 回答