Sails JS护照HTTP 401

4
我正在尝试使用passport http包保护我的 sails js rest api,但是目前我无法确定代码中的错误在哪里。我使用了这个 repo 和这个 tutorial 来了解这应该如何工作。我的问题是我的代码总是返回401。我真的不知道要在哪里寻找错误。如果您需要更多关于我的代码的信息,请评论。Bruno
编辑:我找到了问题的源头(在@Viktor的帮助下)。我只是不太理解HTTP-Basic身份验证的工作原理。现在的问题是,我如何发送我的auth凭据和数据?如果我只是测试具有auth(...)路由的路由,它们就有效...但是我如何添加数据?或者我必须先进行身份验证,然后在第二个请求中发送数据?

passport.js

var passport = require('passport');
var BasicStrategy = require('passport-http').BasicStrategy;
var bcrypt = require('bcrypt');

passport.serializeUser(function(user, done) {
  done(null, user.id);
});

passport.deserializeUser(function(id, done) {
  User.findOne({
    id: id
  }, function(err, user) {
    done(err, user);
  });
});

passport.use('user-authentication', new BasicStrategy(
  function(mail, password, done) {
    sails.log.error("hallo");
    User.findOne({
      mail: mail
    }, function(err, user) {
      if (err) {
        return done(err);
      }

      if (!user) {
        return done(null, false, {
          message: 'Incorrect email.'
        });
      }

      // Make sure the password is correct
      bcrypt.compare(password, user.password, function(err, isMatch) {
        if (err) {
          return done(err);
        }

        // Password did not match
        if (!isMatch) {
          return done(null, false, {
            message: 'Invalid Password'
          });
        }

        // Success
        return done(null, user);
      });
    });
  }
));

isAuthenticated.js

var passport = require("passport");


module.exports = function (req, res, ok) {
    passport.authenticate("user-authentication", {
        session: false
    }, function (err, user, info) {
        if (err || !user) {
            res.set("WWW-Authenticate", "Basic realm=\"Restricted\"");

            return res.send("You are not permitted to perform this action", 401);
        }

        req.session.user = user;
        return ok(null, user);

    })(req, res, ok);
};

policies.js

module.exports.policies = {
  '*': true,

  'UserController': {
    update: 'isAuthenticated'
  }
}

UserController.test.js

var request = require('supertest');
var async = require('async');

describe('UserController', function() {

  describe('#new()', function() {
    it('...', function (done) {
      request(sails.hooks.http.app)
      .post('/user/new')
      .send({ own_number: '654122', password: 'test', mail: 'test@test.com', device_id: '1234', numbers: [1234567] })
      .expect(200)
      .end(done);
    });
  });

  describe('#update()', function(){
    it('...', function (done) {
      async.series([

        function(callback){
          request(sails.hooks.http.app)
          .post('/contact/update')
          .send({ number: 1234, mail: "test@test.com", password: "test" })
          .expect(200)
          .end(callback);
        },

        function(callback){
          request(sails.hooks.http.app)
          .post('/user/update')
          .send({ numbers: [1234], mail: "tet@test.com", password: "test" })
          .expect(200)
          .end(callback);
        }
      ], done);
    });
  });

});

尝试使用“Basic”而不是用户身份验证。 - Zoran Pandovski
好的,但我认为我可以命名不同的策略。 - Bruno
https://github.com/jaredhanson/passport-http 希望这能帮到你。 - Zoran Pandovski
2个回答

0

这里的文档中可以看出,您需要用户ID和密码。因此,查看您的代码,您在userid的位置上使用了mail,这就是为什么您会收到401或者至少可以开始查找的原因。如果您需要验证这一点,可以查看这里的passport-http基本策略

passport.use(new BasicStrategy( function(userid, password, done) { User.findOne({ mail: userid, password: password }, function (err, user) { done(err, user); }); } ));


0

对我来说没问题 - 一旦数据库中有有效用户,我就能够进行身份验证、访问和管理用户数据。当用户数据库为空时,你会一直得到401错误,因为这些策略不允许你创建第一个要进行身份验证的用户。在config/policies.js中暂时禁用UserController的策略,可以让你有机会创建第一个用户。

假设你的数据库中至少有一个有效用户,让我们缩小问题范围。在isAuthenticated.js中记录err和user,你得到了什么输出?如果得到null和false,那么在passport.js的不同步骤中发生了什么 - 你能否通过电子邮件地址在数据库中找到用户,并且密码是否匹配?

你是否有自定义路由和控制器操作,还是使用蓝图?

编辑:使用HTTP基本身份验证,你的更新测试将如下所示:

describe('#update()', function(){
  it('...', function (done) {
    async.series([

      function(callback){
        request(sails.hooks.http.app)
        .post('/contact/update')
        .auth('test@test.com', 'test')
        .send({ number: 1234, mail: "test@test.com", password: "test" })
        .expect(200)
        .end(callback);
      },

      function(callback){
        request(sails.hooks.http.app)
        .post('/user/update')
        .auth('test@test.com', 'test')
        .send({ numbers: [1234], mail: "tet@test.com", password: "test" })
        .expect(200)
        .end(callback);
      }
    ], done);
  });
});

错误为null且用户为false(正如您建议的)。信息显示:“Basic Realm =” Users“”。最让我困惑的是,每次我尝试在passport.use('user-authentication', ...函数内部记录某些内容时,什么也不会发生。我使用自定义路由,并将发布我的测试函数...可能我在那里出现了错误... - Bruno
@Bruno,你在数据库中有一个可以登录的用户吗? - Viktor
是的,我有,并且我更改了策略,所以新用户可以随时创建。 - Bruno
@Bruno 针对 UserController.update 方法,如果您需要通过策略在服务器端进行身份验证,请确保在测试中也配置了客户端的身份验证。使用 supertest 的 auth() 方法即可实现。仅将用户名和密码作为请求体 (send()) 的一部分发送并不会执行 HTTP 基本身份验证。 - Viktor
@Bruno 关于您新增的问题:您应该能够在同一请求中进行身份验证(auth())和发送数据(send())。 - Viktor
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接