Sails.js с аутентификацией паспорта-http-носителя не работает

Я использую несколько стратегий с паспортом (локальные и на предъявителя). Логин с локальной стратегией работает. Мы генерируем токен после входа в систему, и токен сохраняется в Redis. После первоначального входа в систему я хочу использовать аутентификацию носителя без сеанса, если токен находится в Redis. Если я отправлю правильный токен, я могу запросить Redis и получить пользовательские данные, но узел по-прежнему отправляет ответ 403 вместо ожидаемого кода состояния 200. Если токен не найден в redis, то паруса вылетают со следующей ошибкой:

 /workspace/rs-api-sails/node_modules/redis/index.js:587
            throw err;
                  ^
Error: Can't set headers after they are sent.
  at ServerResponse.OutgoingMessage.setHeader (http.js:691:11)
  at ServerResponse.res.setHeader (/workspace/rs-api-sails/node_modules/sails/node_modules/express/node_modules/connect/lib/patch.js:59:22)
  at allFailed (/workspace/rs-api-sails/node_modules/passport/lib/passport/middleware/authenticate.js:153:13)
  at attempt (/workspace/rs-api-sails/node_modules/passport/lib/passport/middleware/authenticate.js:232:28)
  at Context.delegate.fail (/workspace/rs-api-sails/node_modules/passport/lib/passport/middleware/authenticate.js:227:9)
  at Context.actions.fail (/workspace/rs-api-sails/node_modules/passport/lib/passport/context/http/actions.js:35:22)
  at verified (/workspace/rs-api-sails/node_modules/passport-http-bearer/lib/strategy.js:125:19)
  at /workspace/rs-api-sails/config/bootstrap.js:40:18
  at try_callback (/workspace/rs-api-sails/node_modules/redis/index.js:580:9)
  at RedisClient.return_reply (/workspace/rs-api-sails/node_modules/redis/index.js:670:13)
10 Dec 13:25:15 - [nodemon] app crashed - waiting for file changes before starting...

Вот код для аутентификации носителя в bootstrap.js:

passport.use(new BearerStrategy(
  function(token, done) {
    var redis = require("redis"),
    client = redis.createClient(null, null, {detect_buffers: true});

    client.get(token, function (err, reply) {
      if (reply === null) {
        // if token is not a key in redis, node throws the headers already sent error
        return done(null, false);
      } else {
        User.findOne({ id: reply.toString() }).done(function(err, user) {
          sails.log(user);

          // here we get the user data from waterline but node still sends a 403
          return done(null, user);
        });
      }
    });
  }
));  

Этот код находится в policy/isAuthenticated.js:

module.exports = function(req, res, next) {
  var passport = require('passport');    

  passport.authenticate('bearer', { session: false })(req, res, next);  

  // User is allowed, proceed to the next policy, 
  // or if this is the last policy, the controller
  if (req.isAuthenticated()) {
    return next();
  }

  // User is not allowed
  // (default res.forbidden() behavior can be overridden in `config/403.js`)
  return res.forbidden('You are not permitted to perform this action.');
};

Я новичок в узле, любая помощь очень ценится!


person noahpiper    schedule 10.12.2013    source источник


Ответы (1)


Обновление: кажется, теперь работает после нескольких изменений в policy/isAuthenticated.js:

var passport = require('passport');   

module.exports = function(req, res, next) { 

  passport.authenticate('bearer', { session: false }, function(err, user, info) {

    if (req.isAuthenticated()) {
      // user is allowed through local strategy
      return next();
    }  

    if (err) {
      return res.send(403, { error: 'Error: ' + info });        
    }

    if (!user) {
      return res.send(403, { error: 'Invalid token' });
    } 

    if (user) {
      sails.log(user);
      return next();
    }

    // (default res.forbidden() behavior can be overridden in `config/403.js`)
    return res.forbidden('You are not permitted to perform this action.');    

  })(req, res, next);

};
person noahpiper    schedule 12.12.2013