Authentication Meteor自定义登录错误:访问被拒绝
使用meteor@1.1.6、帐户基础、帐户密码和 一点背景: 我正在编写一个web应用程序,允许用户从我们的咖啡馆购买零食,作为Meteor概念的证明。该应用程序在集群中分为两个服务:管理零食和购物的咖啡厅服务和管理用户和身份验证的用户服务。我们希望分离,因为将来我们将有其他服务订阅同一组用户,我们不想在多个地方管理用户 什么有效 用户使用LDAP凭据登录到用户服务。如果名称为Meteor的用户帐户不存在,将使用其ldap信息创建一个新帐户。这些帐户以Meteor允许的默认属性发布。用户将获得一个默认PIN码作为密码,用于订阅服务(目前他们无法更改) cafe应用程序订阅用户服务上的Meteor.users出版物,然后显示所有活动用户。由于cafe应用程序设计为在平板电脑上运行,我们希望尽量减少输入,因此我们允许用户通过触摸用户名来选择帐户。之后,将为他们提供一个pin键盘,用于输入他们的pin(密码),该pin将被散列并通过集群发送,以便在用户服务上进行身份验证。然后,用户服务调用Authentication Meteor自定义登录错误:访问被拒绝,authentication,meteor,meteor-accounts,Authentication,Meteor,Meteor Accounts,使用meteor@1.1.6、帐户基础、帐户密码和 一点背景: 我正在编写一个web应用程序,允许用户从我们的咖啡馆购买零食,作为Meteor概念的证明。该应用程序在集群中分为两个服务:管理零食和购物的咖啡厅服务和管理用户和身份验证的用户服务。我们希望分离,因为将来我们将有其他服务订阅同一组用户,我们不想在多个地方管理用户 什么有效 用户使用LDAP凭据登录到用户服务。如果名称为Meteor的用户帐户不存在,将使用其ldap信息创建一个新帐户。这些帐户以Meteor允许的默认属性发布。用户将获得
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操作。如果您这样做了,请检查您在本机驱动程序(服务器代码中的允许/拒绝规则)@billybobbonetMeteor.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});