假设我在服务器端有一个名为connectServer
的方法:
Meteor.methods({
connectServer: function(data) {
<check if connection has valid data.accessToken from RESTful end point>
if (valid) {
var userId = Accounts.createUser({"email": data.email});
this.setUserId(userId);
}
}
});
此方法的问题在于,它似乎不会在服务器上触发任何"登录连接"操作。我当前正在使用meteor-user-status
,当this.setUserId(userId)
更新时,不会调用事件UserStatus.events.on("connectionLogin", function(fields) { ... })
。有什么方法可以在服务器上手动触发"登录连接"操作吗?谢谢
注意:我没有使用Meteor的客户端,所以我想在服务器端这样做。
查看代码,您可以发出connectionLogin
事件:
UserStatus.events.emit("connectionLogin", {
userId: userId
connectionId: connection.id
ipAddr: connection.clientAddress
userAgent: connection.httpHeaders['user-agent']
loginTime: date
});
这似乎是一件可以做的事情,但请记住,如果包更新了,某些内容发生了更改,您的代码可能会在您没有注意到的情况下崩溃。
下一个需要插入的地方是Accounts
包(因为meteor-user-status
使用Accounts.onLogin()
方法),但我仔细研究了一下,找不到简单的方法。
您的最后一个选项是将用户登录到客户端。您可以生成一个令牌,并允许客户端使用该令牌登录。例如:
// Server method
Meteor.methods({
connectServer: function(data) {
<check if connection has valid acess token>
if (valid) {
var userId = Accounts.createUser({"email": data.email});
var stampedLoginToken = Accounts._generateStampedLoginToken();
Accounts._insertLoginToken(userId, stampedLoginToken);
return stampedLoginToken;
}
}
});
// Client
Meteor.call('connectServer', function(error, result){
if(!error) Meteor.loginWithToken(result.token);
});
在服务器上验证用户的简单过程
从参数电子邮件中查找用户(如果存在)
var user = Meteor.users.findOne({
'emails.address': data.email
});
如果用户找到
if (user) {
//get paramter password
var password = data.password;
//authenticate user
var result = Accounts._checkPassword(user, password);
客户端调用方法
Meteor.call('loginUser', {email: "vxxxxx@xxxx.com", password: "123456"}, function (error, result) {
if (!error) Meteor.loginWithToken(result.token);
});
全代码
// Server method
Meteor.methods({
loginUser: function (data) {
//find user if exist from paramter email
var user = Meteor.users.findOne({
'emails.address': data.email
});
//if user is found
if (user) {
//get paramter password
var password = data.password;
//authenticate user
var result = Accounts._checkPassword(user, password);
if (result.error) {
return result.error;
} else {
return result;
}
} else {
//if user is not found
return {
error: "user not found"
}
}
}
});
客户端调用方法
Meteor.call('loginUser', {email: "vxxxxx@xxxx.com", password: "123456"}, function (error, result) {
if (!error) Meteor.loginWithToken(result.token);
});
你能给createUser
添加一个回调并告诉我们会发生什么吗?我不确定这是否能解决问题,但我很确定你也需要设置一个密码,比如:
Accounts.createUser({
email: data.email,
password: data.password
}, function(err, res){
console.log(err, res);
}
});
否则,如果你想让用户选择密码,我没有看到你的Accounts.sendEnrollmentEmail(userId, [email])
。
这是一个示例代码,我还在其中添加了令牌发布逻辑。如果您不想使用Meteor方法(例如通过HTTP调用或GraphQL调用登录),则之前的答案是不够的,因为它不会生成auth token
。它可能适用于旧版本(因为我们使用Meteor隐藏功能,预计会有突破性的变化),或者如果你使用Meteol方法,但在我的情况下不行。我的代码在Meteor 1.8.3上进行了测试。
// Suppose that userSelector = {username:"foobar"} or {email:"whatever@stackoverflow.com}
const user = Accounts._findUserByQuery(userSelector);
// TODO check that your user is valid (not null, have password...
const passwordCheck = Accounts._checkPassword(
user,
options.password
);
// TODO check that passwordCheck is valid
const stampedLoginToken = Accounts._generateStampedLoginToken();
Accounts._insertLoginToken(userId, stampedLoginToken);
return {
userId,
token: stampedLoginToken.token
};
注意:这不是一个安全的版本!我只是想演示一下逻辑。您还需要检查每个中间结果,如果可能的话,重新引入Meteor帐户的"_attemptLogin"逻辑