Sails.js + Passport.js authentication through websockets

前端 未结 4 1477
醉梦人生
醉梦人生 2020-12-08 04:22

When I use Sails.js with Passport.js, the isAuthenticated method does not exist on the req object when requested through websocket.

Could anyone tell me why this hap

相关标签:
4条回答
  • 2020-12-08 04:55

    @ataman is exactly right. Express middleware that you install using the express.customMiddleware config is only applied to Express HTTP requests.

    To get passport to work for all requests, use it in your policies:

    // e.g. 
    // config/policies.js
    module.exports = {
      SomeController: {
        someaction: function somePassportMiddlewareFn() {}
      }
    };
    
    0 讨论(0)
  • 2020-12-08 04:58

    Alternatively, you can hijack the 'router:request' event to plug in passport for socket requests. I do this in '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();
    };
    

    With this approach you don't need special handling for checking socket request authentication in policies. You do still need to hook up passport for non socket requests by way of express middleware.

    0 讨论(0)
  • 2020-12-08 05:01

    Another way to extend socket.io req with the passport defined methods login, logout, ... is to rewrite the policy or middleware as below

    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 讨论(0)
  • 2020-12-08 05:16

    Please try to check for req.session.passport.user. It will contain user info when logged in, and will be undefined otherwise. Works for me with any type of request.

    I think this happens because in case of WebSocket request, "req" is actually fake request object. It created and passed directly to Express' router, bypassing all Express' middleware, including Passport's one

    0 讨论(0)
提交回复
热议问题