33

当我将 Sails.js 与 Passport.js 一起使用时,当通过 websocket 请求时,req 对象上不存在 isAuthenticated 方法。

谁能告诉我为什么会这样?

4

4 回答 4

25

或者,您可以劫持“路由器:请求”事件以插入通行证以进行套接字请求。我在 '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();
};

使用这种方法,您不需要特殊处理来检查策略中的套接字请求身份验证。您仍然需要通过快速中间件为非套接字请求连接护照。

于 2013-08-20T19:13:03.337 回答
14

请尝试检查req.session.passport.user。登录时它将包含用户信息,否则将未定义。适用于任何类型的请求。

我认为这是因为在 WebSocket 请求的情况下,“req”实际上是假请求对象。它创建并直接传递给 Express 的路由器,绕过所有 Express 的中间件,包括 Passport 的中间件

于 2013-07-21T00:37:58.800 回答
11

@ataman 是完全正确的。您使用express.customMiddleware配置安装的 Express 中间件仅适用于 Express HTTP 请求。

要让护照适用于所有请求,请在您的政策中使用它:

// e.g. 
// config/policies.js
module.exports = {
  SomeController: {
    someaction: function somePassportMiddlewareFn() {}
  }
};
于 2013-07-22T17:41:49.817 回答
0

使用护照定义的方法 login、logout、... 扩展 socket.io req 的另一种方法是重写策略或中间件,如下所示

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)
于 2015-05-20T06:58:43.530 回答