Safe to store complete user info in session with S

2019-07-24 16:28发布

I'm building a Sails.js app that includes a user login. As the documentation instructs, when a user signs in, the session records her id in the session accordingly:

req.session.userId = createdUser.id;

In most of the examples, each route performs a lookup on this ID, if it's present, and sends the authenticated user to the view if found. This strikes me as very inefficient. EVERY view needs to know if there's a signed-in user in order to display her name in the upper left corner. So, if I understand right, every view includes a trip to the database to look up the user, even if I reduce the amount of code by creating a policy that performs this lookup for every route.

What I would rather do is record the user's information in the session so that, once she is authenticated, that information is automatically present to every view:

req.session.userId = createdUser.id;
createdUser.loggedIn = true;
req.session.user = createdUser;
// the createdUser object does NOT contain the encrypted password or other sensitive info

This then allows me to just check in the template for a signed-in user like so from the layout parent template (and any child template). (I'm using server-side views.)

{% if (session.user && session.user.loggedIn) %}
<li><a href="/profile/{{ session.user.id }}">Hi there, {{ session.user.username }}</a></li>
{% else %}
<li><a href="/signin">Sign In (if you want)</a></li>
{% endif %}

My question is whether this poses a security risk of any kind. It seems MUCH more efficient than looking up the User in every view, but perhaps there's a reason that documentation seems to advise this?

1条回答
乱世女痞
2楼-- · 2019-07-24 16:43

In most of the examples, each route performs a lookup on this ID, if it's present, and sends the authenticated user to the view if found

FYI, ideally this should be handled by a policy.

This strikes me as very inefficient. EVERY view needs to know if there's a signed-in user in order to display her name in the upper left corner. So, if I understand right, every view includes a trip to the database to look up the user, even if I reduce the amount of code by creating a policy that performs this lookup for every route.

Either you make extra roundtrips to the database or you bloat your sessions. Both have their pros and cons. E.g. when creating a backend application that does not have to scale, I do not care about this extra database lookups. However when I have hundred thousands of users I should care. You have to consider this when you architect your application. Applications that need to scale like to use e.g. redis as a session store for optimization.

So to answer your question, yes it is okay to store username etc. in the session object to avoid extra database lookups. I am not a security expert, but I would not suggest to store any sensitive user information in the session like passwords.

BTW I highly recommend using http://passportjs.org/. It integrates with sails very well.

To get you started:

  1. http://iliketomatoes.com/implement-passport-js-authentication-with-sails-js-0-10-2/
  2. https://www.airpair.com/express/posts/expressjs-and-passportjs-sessions-deep-dive

In this example you can see how username, email and the roles of the user are stored in the session object:

passport.serializeUser(function(user, done) {
    var sessionUser = { _id: user._id, name: user.name, email: user.email, roles: user.roles }
    done(null, sessionUser);
});
查看更多
登录 后发表回答