Express cookieSession and Mongoose: how can I make request.session.user be a Mongoose model?

mikemaccana

When a new user account is created, I create newUser, a Mongoose model instance that looks like:

_events: Object
errors: undefined
isNew: false
save: function () {
arguments: null
caller: null
_doc: Object
  name: 'Joe Smith'
...

The actual data for the object is in the _doc property, though getters and setters exist so you can run:

user.name = 'Jane Doe' 

and that will work fine. I run:

request.session.user = newUser;

To save the user to the session. So far, so good.

However, in subsequent requests, request.session.user seems to be only the stuff in _doc. Eg:

name: 'Joe Smith'

Which is nice, but that means I can't run eg, request.session.user.save() to save changes.

I could simply make some middleware to look up the user associated with the data. But I'd like to know more about what Express and Mongoose are doing here.

How can I make request.session.user be a Mongoose model?

Update: my current middleware hack:

// Use as a middleware on routes which need users
// TODO: only needed due to request.session.user being saved weirdly
var rehydrateUser = function(request, response, next) {
  if ( request.session.user ) {
    var hydrated = request.session.user.save
    if ( ! hydrated ) {
      console.log('Rehydrating user...');
      models.User.findOne({ somefield: request.session.user.somefield }, function (err, user) {
        if ( err ) {
          request.session.error = 'User not found in DB!';
          request.redirect('/');
        } else {
          request.session.user = user;          
          console.log('Rehydrated user! All repos already being monitored.');
          next();
        }
      })
    } else {
      next();
    }
  } else {
    console.log('No user in session')
    next();
  }
}
moka

Express session is stored as separate storage and has limitations to what can be stored there. It cannot store prototype data (methods). Look at it more like key<>value storage.

Reasons for this is that session can be stored anywhere (pretty much), such as: process memory; databases (mongodb); redis; etc.

Because of this, once you put anything in session object and request is finished, express will take session data, parse it and stick into session store just as pure object. By default it is process memory, but as mentioned before - can be any other storages.

So when next http request happens, session middleware will try to restore session using cookie (if it is used) data in request headers, and will ask session storage to provide data back. As it is already formatted - it will not have .prototype stuff but just data (object, array, string, number, and other simple stuff).

So you need to create Model out of that data again.
You can do by middleware in express. So in app.configure straight after defining session you can do this:

app.use(function(req, res, next) {
  if (req.session && req.session.user) {
    req.session.user = new UserModel(req.session.user);
  }
  return next();
});

This will check if session is defined as well as user. And then will recreate mongoose model out of that data.

As mentioned here in comments - you should not store user data in session as it will lead to inconsistencies due to split of responsibilities over ownership of data. So store just ID of user, and then using middleware load it from Database.

app.use(function(req, res, next) {
  if (req.session && req.session.userID) {
    UserModel.findById(req.session.userID, function(err, user) {
      if (!err && user) {
        req.user = user;
        next();
      } else {
        next(new Error('Could not restore User from Session.'));
      }
    });
  } else {
    next();
  }
});

After you can create middleware to check if user is logged in:

function userRequired(req, res, next) {
  if (req.user) {
    next();
  } else {
    next(new Error('Not Logged In');
  }
}

And use it like that:

app.get('/items', userRequired, function(req, res, next) {
  // will only come here if user is logged in (req.user !== undefined)
});

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

How to I get the results of a call to a method that is located in a Mongoose model?

分類Dev

How to use Symbols with Mongoose model?

分類Dev

Mongoose: How can I access a select:false property in a schema method?

分類Dev

How can I sort then limit an array of results in mongoose?

分類Dev

Can't Catch Error for Mongoose Model Save

分類Dev

When making a POST request for a subdocument it comes back as undefined? mongoose, express

分類Dev

How to query nested data in mongoose model

分類Dev

Why can I not chain .catch when calling mongoose Model.create in node

分類Dev

Node + Express + Passport + Mongoose:req.user Undefined

分類Dev

Retrieving model using mongoose

分類Dev

Array in User Schema - mongoose

分類Dev

mongoose user defined methods

分類Dev

How do I increment a property of a subdocument in Mongoose?

分類Dev

How to pass the timestamp in the query param of NodeJS (Express + Mongoose)

分類Dev

how does one update numbers inside mongoose model nested array

分類Dev

How can I make a custom "POST" request on client side?

分類Dev

mongoose how to prevent user already with username to modify username

分類Dev

Why can't I set up a DB with Mongoose?

分類Dev

mongoose make sure document is unique

分類Dev

How to mock mongoose?

分類Dev

how to group by in mongoose

分類Dev

how to filter model.find query results with model.populate query results in mongoose?

分類Dev

How to make custom authentication not based on User model

分類Dev

Global variable in express using mongo/mongoose

分類Dev

Discord.py: How can I make a command that i can only do with my user ID?

分類Dev

Mongoose Deep Populate limiting intermediate model

分類Dev

Getting mongoose not defined error in model file

分類Dev

Good practice for parent model field udpate with mongoose

分類Dev

Mongoose Model, cleaning/parsing an Array efficiently

Related 関連記事

  1. 1

    How to I get the results of a call to a method that is located in a Mongoose model?

  2. 2

    How to use Symbols with Mongoose model?

  3. 3

    Mongoose: How can I access a select:false property in a schema method?

  4. 4

    How can I sort then limit an array of results in mongoose?

  5. 5

    Can't Catch Error for Mongoose Model Save

  6. 6

    When making a POST request for a subdocument it comes back as undefined? mongoose, express

  7. 7

    How to query nested data in mongoose model

  8. 8

    Why can I not chain .catch when calling mongoose Model.create in node

  9. 9

    Node + Express + Passport + Mongoose:req.user Undefined

  10. 10

    Retrieving model using mongoose

  11. 11

    Array in User Schema - mongoose

  12. 12

    mongoose user defined methods

  13. 13

    How do I increment a property of a subdocument in Mongoose?

  14. 14

    How to pass the timestamp in the query param of NodeJS (Express + Mongoose)

  15. 15

    how does one update numbers inside mongoose model nested array

  16. 16

    How can I make a custom "POST" request on client side?

  17. 17

    mongoose how to prevent user already with username to modify username

  18. 18

    Why can't I set up a DB with Mongoose?

  19. 19

    mongoose make sure document is unique

  20. 20

    How to mock mongoose?

  21. 21

    how to group by in mongoose

  22. 22

    how to filter model.find query results with model.populate query results in mongoose?

  23. 23

    How to make custom authentication not based on User model

  24. 24

    Global variable in express using mongo/mongoose

  25. 25

    Discord.py: How can I make a command that i can only do with my user ID?

  26. 26

    Mongoose Deep Populate limiting intermediate model

  27. 27

    Getting mongoose not defined error in model file

  28. 28

    Good practice for parent model field udpate with mongoose

  29. 29

    Mongoose Model, cleaning/parsing an Array efficiently

ホットタグ

アーカイブ