使用[email protected],賬戶基礎,賬戶密碼和Meteorhacks cluster。流星自定義登錄錯誤:訪問被拒絕
一點背景:
我正在寫一個web應用程序,允許用戶從我們作爲一個驗證的概念流星咖啡館購買小吃。這個應用程序分爲兩個羣集內的服務:管理點心和購買的咖啡館服務,以及管理用戶和認證的用戶服務。我們希望分離,因爲將來我們將有其他服務訂閱同一組用戶,並且我們不希望在多個地方管理用戶。
什麼工作
用戶登錄到與LDAP憑證用戶服務。如果不存在具有名稱的Meteor用戶帳戶,則會使用其ldap信息創建一個新帳戶。這些帳戶與Meteor允許的默認屬性一起發佈。用戶被賦予一個默認的PIN碼作爲用於訂閱服務的密碼(現在他們不能改變它)。
cafe應用程序訂閱Meteor.users發佈的用戶服務,然後顯示所有活動用戶。由於咖啡廳應用程序旨在在平板電腦上運行,因此我們希望儘量減少打字,因此我們允許用戶通過觸摸用戶名來選擇帳戶。在那之後,他們被提供一個管腳焊盤來鍵入他們的管腳(口令),這個管腳將被散列並通過集羣發送,以便在用戶服務上進行驗證。然後,用戶服務調用Accounts._checkPassword
來驗證請求,並返回一個包含userId
和/或任何錯誤的對象。我們正在使用名爲loginWithPin
的自定義登錄方法,它與loginWithPassword
基本相同。所有這些都很好用。
什麼行不通
當認證API返回它的結果,就會出現問題。在輸入密碼右邊之前,所有內容都是正確的。我們的自定義方法loginWithPin
總是返回錯誤,但奇怪的是您輸入正確的PIN碼。身份驗證過程傳遞用戶服務層並傳回像{ userId: '...' }
這樣的對象,但自定義方法會以Access Denied
爲原因引發403錯誤。
我假設一個自定義登錄方法返回一個userId對象實際上會通過該用戶名登錄用戶。那,並且我找不到在accounts-base
或accounts-password
任何地方會引發403拒絕訪問錯誤。
TLDR
使用正確針的時候,但驗證是在另一個應用程序的API發生在用戶的密碼實際上我的生活習俗loginWithPin
方法返回一個[403] Access Denied
錯誤。
咖啡應用代碼
客戶/ 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);
}
});
被燒成機智的錯誤h Access Denied
是在client/enter_pin/enter_pin.js
中找到的一個,如果Meteor.user()
未定義,則是因爲登錄未發生。然而,即使身份驗證API成功返回一個包含userId的對象,該錯誤也會觸發。
UPDATE
網吧應用服務器/ 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而不覆蓋它。
是'loginWithPin'客戶端(我的猜測是在'both'文件夾中)?如果是這樣,你可能會在'loginWithPin'中使用CUD操作。如果你這樣做,檢查你是否有本地驅動程序的授權(允許/拒絕服務器代碼中的規則) – Billybobbonnet
@Billybobbonnet'Meteor.loginWithPin'在'client/login.js'中,所以是的。但是在這個函數中唯一發生的事情是檢查'用戶名','SHA256'引腳,並在流星文檔後面調用Accounts.callLoginMethod。包括對所有允許規則的授權似乎沒有辦法。 – chazsolo
我看着流星文檔,我不能看到一個'Accounts.callLoginMethod'。什麼是你的功能的名稱? – Billybobbonnet