Sails JS 护照 http 401

Posted

技术标签:

【中文标题】Sails JS 护照 http 401【英文标题】:Sails JS passport http 401 【发布时间】:2017-02-28 23:53:10 【问题描述】:

我正在尝试在护照 http 包的帮助下保护我的sails js rest api,但目前我无法弄清楚我的代码中的错误在哪里。 我使用了这个repo 和这个tutorial 来了解它应该如何工作。我的问题是我的代码总是返回 401。 我真的不知道在哪里寻找错误。如果您需要有关我的代码的更多信息,请发表评论。 布鲁诺

编辑: 我找到了问题的根源(在@Viktor 的帮助下)。我只是不太了解 HTTP-Basic 身份验证的工作原理。现在的问题是如何发送我的身份验证凭据和我的数据?如果我只是用 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);
    );
  );

);

【问题讨论】:

尝试使用“基本”而不是用户身份验证 好的,但我想我可以说出不同的策略 github.com/jaredhanson/passport-http希望对你有帮助 【参考方案1】:

对我有用——一旦数据库中有有效用户,我就可以进行身份​​验证以及访问和管理用户数据。当然,对于一个空的用户数据库,您将一直得到401,因为这些策略甚至不允许您创建第一个进行身份验证的用户。暂时禁用 config/policies.js 中的 UserController 策略可以让您有机会创建第一个用户。

假设您在数据库中至少有一个有效用户,让我们缩小问题范围。在isAuthenticated.js 中记录erruser 得到什么输出?如果你得到nullfalse,在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);
  );
);

【讨论】:

err 为 null 且 user 为 false (如您所建议)。信息显示“基本领域 =“用户”。最让我困惑的是,每次我尝试在 passport.use('user-authentication', ... 函数中记录一些东西时,什么都没有发生。我使用自定义路由,我会发布我的测试功能......可能我有一个错误...... @Bruno 你在数据库中有用户登录吗? 是的,我确实有,并且我更改了策略,以便始终可以创建新用户 @Bruno 现在使用更新后的策略,用户创建在您的测试中是否正常工作,并且创建测试是否通过?我看到您在测试中没有设置任何身份验证。将.auth('test@test.com', 'test') 添加到您的更新测试调用中怎么样?见supertest documentation。 @Bruno 我不知道否决票来自哪里或出于什么原因,但正如我所提到的,您的 Passport.js 配置适用于我的新 Sails.js 项目,其中包含蓝图路线和控制器。只要我对蓝图路由和控制器(路径、方法等)进行必要的调整并将我在上一条评论中提到的 auth() 调用添加到更新测试中,您的测试就可以正常工作。如果您仍然有身份验证问题,如果您也发布相关模型、控制器和路由,可能会更容易找到错误。【参考方案2】:

从文档here 它显示您需要用户名和密码。因此,查看您的代码,您可以使用邮件代替用户 ID,这就是为什么您会收到 401 或至少可以开始查找的原因。如果您需要验证这一点,您可以查看passport-http basic strategy here。

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

【讨论】:

以上是关于Sails JS 护照 http 401的主要内容,如果未能解决你的问题,请参考以下文章

Sails.js 0.11 和护照:“缺少凭据”错误

Sails.js 中的 JWT 和护照

带有护照推特的sails.js

如何在sails.js 中启用http/2

护照-jwt sequelize 401 总是

使用 Passport.js 和 Sails.js 注册后如何重定向到特定位置?