使用meteor@1.1.6,帐户库,帐户密码和气象站群。
一些背景:
我正在编写一个网络应用程序,允许用户从我们的咖啡馆购买零食,作为Meteor概念的证明。这个应用程序在集群中分为两个服务:管理零食和购买的咖啡馆服务,以及管理用户和身份验证的用户服务。我们希望实现这种分离,因为将来我们将有其他服务订阅同一组用户,而且我们不希望管理多个地方的用户。
什么工作
用户使用LDAP凭据登录用户服务。如果不存在具有其名称的Meteor用户帐户,则将使用其ldap信息创建一个新帐户。这些帐户是使用Meteor允许的默认属性发布的。用户将获得一个默认的PIN号,作为在订阅服务时使用的密码(目前他们不能更改它)。
cafe应用程序订阅用户服务上的Meteor.users发布,然后显示所有活动用户。由于咖啡馆的应用程序是为了在平板电脑上运行,所以我们希望尽量减少输入,所以我们允许用户通过触摸用户名来选择他们的帐户。在此之后,将为他们提供一个输入密码的引脚板,该密码将被散列并发送到集群上,以便在用户服务上进行身份验证。然后,用户服务调用Accounts._checkPassword对请求进行身份验证,并将返回带有userId和/或任何错误的对象。我们使用的是名为loginWithPin的自定义登录方法,它基本上与loginWithPassword相同。所有这些都很好用。
什么不起作用
当身份验证API返回其结果时,就会出现问题。在输入正确的密码之前,一切都是正确的。我们的自定义方法loginWithPin总是返回一个错误,但奇怪的是当您输入正确的PIN时。身份验证过程传递给用户服务层,并传回像{ userId: '...' }这样的对象,但是自定义方法抛出一个以Access Denied为原因的403错误。
我的假设是,自定义登录方法返回一个带有userId的对象,实际上将通过该id登录用户。这一点,我在accounts-base或accounts-password中找不到任何地方会抛出一个403访问被拒绝的错误。
TLDR
我的自定义loginWithPin方法在使用正确的引脚时返回一个[403] Access Denied错误,但是身份验证是在另一个应用程序的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
});
};服务器/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
服务器/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);
}
});使用Access Denied触发的错误是在client/enter_pin/enter_pin.js中发现的错误,如果Meteor.user()是未定义的,这是因为登录没有发生。然而,即使身份验证API成功返回包含userId的对象,也会触发此错误。
更新
cafe应用服务器/cluster.js(在这里我们连接到用户服务)
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});我认为主要的问题在于这里的最后一行,因为我正在重新定义Meteor.users集合。但是,我不知道如何将从用户服务获得的数据准确地同步到服务器上的Meteor.users,而不覆盖它。
发布于 2015-06-12 22:13:30
但是,我不知道如何将从用户服务获得的数据准确地同步到服务器上的Meteor.users,而不覆盖它。
Meteor是为了提供一个简单的SyncData工作流而构建的。
例如,您可以为每个服务使用另一个单独的集合,并对Meteor.users集合有一个引用。
然后,您可以在需要它的地方订阅服务集合。
在您的Meteor.users中将有一个新字段:
pinBasedServices: [
{
service: 'cafe',
pin: 'XXX',
lastLogin: '',
generatedHashTokenFromTheServiceToGetTheDataFrom:'somehash',
/* whatever */
},
{
service: 'cheeseCakeService',
pin: 'XYZ',
/* So on.. */
}
]
我希望,我可以给你另一个方向的想法,不需要覆盖流星收藏品。就在它的基础上。
如果您想以需要的方式拥有数据同步,也可以观察Meteor集合。
https://stackoverflow.com/questions/30734543
复制相似问题