sails.js Use session param in model

两盒软妹~` 提交于 2019-11-27 16:10:54
sgress454

So, if I understand you correctly, you want to avoid lots of code like this in your controllers:

SomeModel.create({companyId: req.session.companyId, ...})
SomeModel.find({companyId: req.session.companyId, ...})

Fair enough. Maybe you're concerned that companyId will be renamed in the future, or need to be further processed. The simplest solution if you're using custom controller actions would be to make class methods for your models that accept the request as an argument:

SomeModel.doCreate(req, ...);
SomeModel.doFind(req, ...);

On the other hand, if you're on v0.10.x and you can use blueprints for some CRUD actions, you will benefit from the ability to override the blueprints with your own code, so that all of your creates and finds automatically use the companyId from the session.

If you're coming from a non-Node background, this might all induce some head-scratching. "Why can't you just make the session available everywhere?" you might ask. "LIKE THEY DO IN PHP!"

The reason is that PHP is stateless--every request that comes in gets essentially a fresh copy of the app, with nothing in memory being shared between requests. This means that any global variables will be valid for the life of a single request only. That wonderful $_SESSION hash is yours and yours alone, and once the request is processed, it disappears.

Contrast this with Node apps, which essentially run in a single process. Any global variables you set would be shared between every request that comes in, and since requests are handled asynchronously, there's no guarantee that one request will finish before another starts. So a scenario like this could easily occur:

  1. Request A comes in.
  2. Sails acquires the session for Request A and stores it in the global $_SESSION object.
  3. Request A calls SomeModel.find(), which calls out to a database asynchronously
  4. While the database does its magic, Request A surrenders its control of the Node thread
  5. Request B comes in.
  6. Sails acquires the session for Request B and stores it in the global $_SESSION object.
  7. Request B surrenders its control of the thread to do some other asynchronous call.
  8. Request A comes back with the result of its database call, and reads something from the $_SESSION object.

You can see the issue here--Request A now has the wrong session data. This is the reason why the session object lives inside the request object, and why it needs to be passed around to any code that wants to use it. Trying too hard to circumvent this will inevitably lead to trouble.

Best option I can think of is to take advantage of JS, and make some globally accessible functions.

But its gonna have a code smell :(

I prefer to make a policy that add the companyId inside the body.param like this:

    // Needs to be Logged
    module.exports = function(req, res, next) {
        sails.log.verbose('[Policy.insertCompanyId() called] ' + __filename);

        if (req.session) {
            req.body.user = req.session.companyId; 
                 //or something like AuthService.getCompanyId(req.session);
            return next();
        }

        var err = 'Missing companyId'; 
        //log ...
        return res.redirect(307, '/');
    };
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!