sails.js Utiliser le paramètre de session dans le modèle

Ceci est une extension de cette question .

Dans mes modèles, tout le monde requirejs la création d’un companyId et tous les filtres doivent être filtrés par la même session companyid.

Avec sails.js , j’ai lu et compris que la session n’est disponible dans le modèle que si je l’injecte à l’aide du contrôleur, mais cela nécessiterait que je code toutes mes actions / contrôleurs avec quelque chose de très, très répétitif. Malheureux.

J’aime sails.js et je veux faire la transition, mais est-ce que quelqu’un peut me décrire un meilleur moyen? J’espère avoir manqué quelque chose.

Donc, si je vous ai bien compris, vous voulez éviter beaucoup de code comme celui-ci dans vos contrôleurs:

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

C’est suffisant. Peut-être craignez-vous que companyId soit renommé à l’avenir ou nécessite un traitement supplémentaire. La solution la plus simple si vous utilisez des actions de contrôleur personnalisées consiste à créer des méthodes de classe pour vos modèles qui acceptent la demande en tant qu’argument:

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

Par contre, si vous êtes sur v0.10.x et que vous pouvez utiliser des plans pour certaines actions CRUD, vous bénéficierez de la possibilité de remplacer les plans par votre propre code , de sorte que toutes vos créations et recherches utilisent automatiquement le companyId de la session.

Si vous venez d’un arrière-plan non-nœud, cela peut tous provoquer des problèmes de tête. “Pourquoi ne peux-tu pas simplement rendre la session disponible partout?” vous pourriez demander. “Comme ils le font en PHP!”

La raison en est que PHP est sans état – chaque requête entrant reçoit essentiellement une nouvelle copie de l’application, aucune mémoire en mémoire n’étant partagée entre les requêtes. Cela signifie que toutes les variables globales ne seront valides que pour la vie d’une seule requête. Ce merveilleux hash $_SESSION est à vous et à vous seul, et une fois la demande traitée, elle disparaît.

Comparez cela avec les applications de nœud, qui s’exécutent essentiellement dans un seul processus. Toutes les variables globales que vous définissez sont partagées entre toutes les demandes qui arrivent. Étant donné que les demandes sont traitées de manière asynchrone, rien ne garantit qu’une demande se terminera avant qu’une autre ne commence. Donc, un scénario comme celui-ci pourrait facilement se produire:

  1. La demande A entre en jeu.
  2. Sails acquiert la session pour la demande A et la stocke dans l’object global $_SESSION .
  3. Request A appelle SomeModel.find() , qui appelle une firebase database de manière asynchrone
  4. Alors que la firebase database fait son effet magique, Request A abandonne son contrôle du thread Node
  5. La demande B entre en jeu.
  6. Sails acquiert la session pour la requête B et la stocke dans l’object global $_SESSION .
  7. Request B abandonne son contrôle du thread pour effectuer un autre appel asynchrone.
  8. La demande A renvoie le résultat de l’appel de la firebase database et lit quelque chose dans l’object $_SESSION .

Vous pouvez voir le problème ici – La demande A a maintenant les mauvaises données de session. C’est la raison pour laquelle l’object de session vit à l’intérieur de l’object de demande et qu’il doit être transmis à tout code qui souhaite l’utiliser. Tenter trop de contourner cela engendrera inévitablement des problèmes.

La meilleure option à laquelle je puisse penser est de tirer parti de JS et de rendre certaines fonctions accessibles au niveau mondial.

Mais ça va avoir une odeur de code 🙁

Je préfère créer une politique qui ajoute le companyId à l’intérieur du body.param comme ceci:

  // 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, '/'); };