gpt4 book ai didi

authentication - Meteor自定义登录报错: access denied

转载 作者:行者123 更新时间:2023-12-01 05:04:01 24 4
gpt4 key购买 nike

使用 meteor@1.1.6、accounts-base、accounts-password 和 Meteorhacks cluster .

一点背景:

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

什么有效

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

咖啡馆应用程序订阅了用户服务上的 Meteor.users 发布,然后显示所有活跃用户。由于咖啡厅应用程序设计为在平板电脑上运行,我们希望尽量减少打字,因此我们允许用户通过触摸他们的用户名来选择他们的帐户。之后,他们会获得一个密码键盘,用于输入他们的密码(密码),该密码将被散列并通过集群发送,以在用户服务上进行身份验证。用户服务然后调用 Accounts._checkPassword 来验证请求,并将返回一个包含 userId 和/或任何错误的对象。我们正在使用一个名为 loginWithPin 的自定义登录方法,它与 loginWithPassword 基本相同。所有这一切都非常完美。

什么不起作用

当身份验证 API 返回结果时,问题就出现了。在您输入正确 密码之前,一切都是正确的。我们的自定义方法 loginWithPin 总是返回错误,但奇怪的是当您输入正确的 PIN 时。身份验证过程通过用户服务层并传回一个对象,如 { userId: '...' } ,但自定义方法抛出 403 错误,Access Denied 作为原因。

我假设返回带有 userId 的对象的自定义登录方法实际上会通过该 id 登录用户。那,我在 accounts-baseaccounts-password 中找不到会引发 403 Access Denied 错误的任何地方。

TLDR

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


咖啡厅应用代码

客户端/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
}
}
}

客户端/登录.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);
}
});

如果 Meteor.user(),则 Access Denied 引发的错误是在 client/enter_pin/enter_pin.js 中发现的错误是未定义的,这是因为没有发生登录。然而,即使身份验证 API 成功返回其中包含 userId 的对象,也会触发此错误。


更新

cafe app server/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 而不覆盖它。

最佳答案

However, I'm at a loss as to how exactly we would sync the data we get from the user-service to Meteor.users on the server without overwriting it.

Meteor 旨在提供简单的 SyncData 工作流程。

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

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

在你的 Meteor.users 中你会有一个新字段:

pinBasedServices: [
{
service: 'cafe',
pin: 'XXX',
lastLogin: '',
generatedHashTokenFromTheServiceToGetTheDataFrom:'somehash',
/* whatever */
},
{
service: 'cheeseCakeService',
pin: 'XYZ',
/* So on.. */
}
]

我希望,我可以给你另一个思考方向,让你不必覆盖 Meteor Collections.. 只需在它的基础上构建。

如果您想以您需要的方式同步数据,您还可以观察 Meteor Collections。

关于authentication - Meteor自定义登录报错: access denied,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30734543/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com