Authentication Meteor自定义登录错误:访问被拒绝

Authentication Meteor自定义登录错误:访问被拒绝,authentication,meteor,meteor-accounts,Authentication,Meteor,Meteor Accounts,使用meteor@1.1.6、帐户基础、帐户密码和 一点背景: 我正在编写一个web应用程序,允许用户从我们的咖啡馆购买零食,作为Meteor概念的证明。该应用程序在集群中分为两个服务:管理零食和购物的咖啡厅服务和管理用户和身份验证的用户服务。我们希望分离,因为将来我们将有其他服务订阅同一组用户,我们不想在多个地方管理用户 什么有效 用户使用LDAP凭据登录到用户服务。如果名称为Meteor的用户帐户不存在,将使用其ldap信息创建一个新帐户。这些帐户以Meteor允许的默认属性发布。用户将获得

使用meteor@1.1.6、帐户基础、帐户密码和

一点背景:

我正在编写一个web应用程序,允许用户从我们的咖啡馆购买零食,作为Meteor概念的证明。该应用程序在集群中分为两个服务:管理零食和购物的咖啡厅服务和管理用户和身份验证的用户服务。我们希望分离,因为将来我们将有其他服务订阅同一组用户,我们不想在多个地方管理用户

什么有效

用户使用LDAP凭据登录到用户服务。如果名称为Meteor的用户帐户不存在,将使用其ldap信息创建一个新帐户。这些帐户以Meteor允许的默认属性发布。用户将获得一个默认PIN码作为密码,用于订阅服务(目前他们无法更改)

cafe应用程序订阅用户服务上的Meteor.users出版物,然后显示所有活动用户。由于cafe应用程序设计为在平板电脑上运行,我们希望尽量减少输入,因此我们允许用户通过触摸用户名来选择帐户。之后,将为他们提供一个pin键盘,用于输入他们的pin(密码),该pin将被散列并通过集群发送,以便在用户服务上进行身份验证。然后,用户服务调用
Accounts.\u checkPassword
对请求进行身份验证,并返回带有
userId
和/或任何错误的对象。我们正在使用一个名为
loginWithPin
的自定义登录方法,它与
loginWithPassword
基本相同。所有这些工作都非常出色

什么不起作用

当认证API返回其结果时,就会出现问题。在输入正确的密码之前,一切都是正确的。我们的自定义方法
loginWithPin
总是返回错误,但奇怪的是当您键入正确的PIN时。身份验证过程在用户服务层上传递,并传回一个对象,如
{userId:'…'}
,但是自定义方法抛出一个403错误,原因是
访问被拒绝

我假设一个自定义登录方法返回一个具有用户id的对象,实际上会通过该id登录用户。我在
帐户库
帐户密码
中找不到会抛出403拒绝访问错误的地方

TLDR

当使用正确的pin时,我的自定义
loginWithPin
方法返回一个
[403]拒绝访问
错误,但身份验证正在用户密码实际所在的另一个应用程序的API上进行


咖啡厅应用程序代码

client/enter_pin/enter_pin.js

//...
if ( //pin fully entered ) {
  Meteor.loginWithPin(password.value, function( err ) {
    if ( Meteor.user() ) {
      // login successful, route to cafe
      Router.go('/cafe');
    } else {
      console.error('An error occurred while logging in: ', err);

      // other stuff to reset pinpad
    }
  }
}
client/login.js

Meteor.loginWithPin = function( pin, callback ) {
  var username = Session.get('selectedUser');

  check(username, String);
  // hash pin before sending it across cluster connection
  pin = Package.sha.SHA256(pin);

  // send login request
  Accounts.callLoginMethod({
    methodArguments: [{
      user: {
        username: username
      },
      pin: pin
    }],
    userCallback: callback
  });
};
server/login.js

Accounts.registerLoginHandler(function( request ) {
  // use runAsync here since login request is asynchronous and we want to pause execution until this returns
  var response = Async.runSync(function( done ) {
    ClusterConnection.call('authenticateUser', request.user.username, request.pin, function( err, res ) {
      if ( !err && !res.error ) {
        console.log('successful login');
        done(null, res);
      } else {
        console.log('unsuccessful login');
        done(null);
      }
    });
  });

  // this should be either { userId: '...' }, or null if an error is present
  return response.result;
});
服务API

server/api.js

Meteor.methods({
  'authenticateUser': function( username, pin ) {
    check(username, String);
    check(pin, String);

    var user = Meteor.users.findOne({username: username});
    var password = {digest: pin, algorithm: 'sha-256'};
    return Accounts._checkPassword(user, password);
  }
});

如果
Meteor.user()
未定义,则在
client/enter\u pin/enter\u pin.js
中发现的
Access Denied
引发的错误是,这种情况是因为未发生登录。然而,即使身份验证API成功返回包含用户ID的对象,也会触发此错误


更新

cafe-app-server/cluster.js(我们连接到用户服务的地方)

我认为主要的问题在于最后一行,因为我正在重新定义Meteor.users集合。但是,我不知道如何准确地将从用户服务获得的数据同步到服务器上的Meteor.users,而不覆盖它

但是,我不知道如何准确地将从用户服务获得的数据同步到服务器上的Meteor.users,而不覆盖它

Meteor是为提供简单的SyncData工作流而构建的

例如,您可以为每个服务使用另一个单独的集合,并引用Meteor.users集合

然后,您可以在需要的地方订阅服务集合

在Meteor.users中,您将拥有一个新字段:

pinBasedServices:[
{
服务:'咖啡馆',
pin:'XXX',
上次登录:“”,
从服务生成HashToken,从以下位置设置数据:“somehash”,
/*随便*/
},
{
服务:'cheeseCakeService',
pin:'XYZ',
/*以此类推*/
}

]
loginWithPin
客户端(我猜它在
两个
文件夹中)?如果是这样,您可能正在
loginWithPin
中使用CUD操作。如果您这样做了,请检查您在本机驱动程序(服务器代码中的允许/拒绝规则)@billybobbonet
Meteor.loginWithPin
位于
client/login.js
中,因此是的。但是在该函数中发生的唯一事情是检查
用户名
SHA256
锁定pin,并在meteor文档之后调用
Accounts.callLoginMethod
。包括对所有允许规则的授权似乎不起作用。我查看了Meteor文档,没有看到
Accounts.callLoginMethod
。你的函数名是什么?@Billybobbonnet我将继续并发布相关代码..并不是说我想固执,而是
Accounts.callLoginMethod()
在Meteor文档中仍然不存在。您是否使用自定义方法扩展了帐户?
Cluster.connect('mongodb://localhost:27017/service-discovery');
Cluster.register('cafe');

EmployeeConn = Cluster.discoverConnection('employees');
EmployeeConn.subscribe('employees');

Meteor.users = new Mongo.Collection('users', {connection: EmployeeConn});