web-dev-qa-db-fra.com

Authentification Sails.js + Passport.js via Websockets

Lorsque j'utilise Sails.js avec Passport.js, la méthode isAuthenticated n'existe pas sur l'objet req lorsqu'il est demandé via websocket.

Quelqu'un pourrait-il me dire pourquoi cela se produit?

32
Elliot Lings

Vous pouvez également pirater l'événement 'router: request' pour brancher le passeport pour les demandes de socket. Je le fais dans 'config/bootstrap.js':

module.exports.bootstrap = function (cb) {

  var passport = require('passport'),
    initialize = passport.initialize(),
    session = passport.session(),
    http = require('http'),
    methods = ['login', 'logIn', 'logout', 'logOut', 'isAuthenticated', 'isUnauthenticated'];

  sails.removeAllListeners('router:request');
  sails.on('router:request', function(req, res) {
    initialize(req, res, function () {
      session(req, res, function (err) {
        if (err) {
          return sails.config[500](500, req, res);
        }
        for (var i = 0; i < methods.length; i++) {
          req[methods[i]] = http.IncomingMessage.prototype[methods[i]].bind(req);
        }
        sails.router.route(req, res);
      });
    });
  });
  cb();
};

Avec cette approche, vous n'avez pas besoin d'un traitement spécial pour vérifier l'authentification de demande de socket dans les stratégies. Vous devez toujours connecter votre passeport pour les demandes autres que de socket via un middleware express.

25
xdissent

Veuillez essayer de vérifier req.session.passport.user . Il contiendra les informations de l'utilisateur une fois connecté et sera indéfini autrement. Fonctionne pour moi avec tout type de demande.

Je pense que cela se produit car dans le cas d'une requête WebSocket, "req" est en fait un objet de requête factice. Il a été créé et transmis directement au routeur Express, contournant tous les middleware Express, y compris celui de Passport.

14
ataman

@ataman a tout à fait raison. Le middleware Express que vous installez à l'aide de la configuration express.customMiddleware est uniquement appliqué aux requêtes HTTP Express.

Pour que le passeport fonctionne avec toutes les demandes, utilisez-le dans vos politiques:

// e.g. 
// config/policies.js
module.exports = {
  SomeController: {
    someaction: function somePassportMiddlewareFn() {}
  }
};
11
mikermcneil

Une autre façon d’étendre socket.io req avec les méthodes définies par le passeport login, logout, ... consiste à réécrire la politique ou le middleware comme indiqué ci-dessous

module.exports = (req, res, next) ->
    if req.isSocket
        req = _.extend req, _.pick(require('http').IncomingMessage.prototype, 'login', 'logIn', 'logout', 'logOut', 'isAuthenticated', 'isUnauthenticated')
    middleware = passport.authenticate('bearer', { session: false })
    middleware(req, res, next)
0
Tommy Tang