在 Meteor 中通过 SMS 登录和注册过程
Signin and signup process via SMS in Meteor
我需要在我的 Meteor 应用程序中进行短信验证。
假设我有一个简单的表单(React 风格,因为我在前端使用 React):
<form onSubmit={ this.submitPhone() }>
<input type='text' size='10' placeholder='Your phone here' />
<input type='submit' value='Send me a code'/>
</form>
用户输入他的 phone 号码并提交表格。之后,短信代码将发送到输入的号码。并出现一个新表格:
<form onSubmit={ this.submitCode() }>
<input type='text' size='5' placeholder='Enter code' />
<input type='submit' value='Sign In'/>
</form>
如果用户正确输入了他的代码,那么 Meteor 应该知道用户已登录(我认为是使用一些 _id)。如果代码不正确,则会显示一条错误消息。
我找到了 Twilio 服务和这个 package,它看起来正是我所需要的。但是完全不知道怎么用
我几个月前在教程中只尝试过 Meteor 的默认帐户 UI 身份验证方式,但实际上我不知道如何做这些事情,尤其是通过 SMS。我不需要我的应用程序中的角色之类的东西,我什至不需要用户名、密码和电子邮件。我只需要有一个用户群 _id
和 phone
。所以我只需要让用户能够登录(第一次登录就是用这种方式注册)。
感谢您的帮助,详细的回答正是我这次所需要的。
首先,您需要安装以下软件包之一:
- http(直接从您的方法调用 Twilio API)或者,
- accolver:twilio-meteor (You can try using the services this package provides off of the official Twilio-Node Helper Library)
接下来,您还应该安装 okland:accounts-phone package to help enable login via phone number. Their GitHub 提供简单易懂的设置说明。
密码
我强烈建议使用密码和 phone 号码创建用户帐户,因为它是一个很好的安全功能,并且在 Meteor 帐户包中默认也是必需的。
验证过程
我将给出一个使用服务器端 Meteor 方法 的示例,对于前端,您可以相应地编写 React 处理程序。
此示例将使用 HTTP 包,如果您愿意,可以在您的代码中修改它以包含其他包装器包,如 twilio-meteor。
第一步:
注册您的用户并发送验证短信。
createNewUser 方法:
'createNewUser': function (password, phoneNumber) {
var min = 10000;
var max = 99999;
var random = Math.floor(Math.random() * (max - min + 1)) + min;
var verified = Meteor.users.find({username: phoneNumber}).fetch();
if (verified.length > 0) {
if (verified.length == 1 && verified[0].profile.isMobileVerified == 'NO') {
Meteor.users.remove({username: phoneNumber});
var user = {username: phoneNumber, password: password, profile: { randomSms: random, isMobileVerified: 'NO' }};
Meteor.call("sendSMS", random, phoneNumber);
Accounts.createUser(user);
return returnSuccess('Successfully created', phoneNumber);
} else {
return returnFaliure('Mobile number already exists', phoneNumber);
}
} else {
var user = {username: phoneNumber, password: password, profile: { randomSms: random, isMobileVerified: 'NO' }};
Meteor.call("sendSMS", random, phoneNumber);
Accounts.createUser(user);
return returnSuccess('Successfully created', phoneNumber);
}
},
发送短信方法:
'sendSMS': function (code, mobile) {
console.log(mobile);
HTTP.call(
"POST",
'https://api.twilio.com/{yyyy-dd-mm}/Accounts/' +
'{TWILIO_APPKEY}' + '/SMS/Messages.json', {
params: {
From: '+11234567890',
To: mobile,
Body: "Greetings! Your OTP is " + code
},
auth: '{TWILIO_APPKEY}' + ':' + '{TWILIO_PASSWORD}'
},
// Print error or success to console
function (error) {
if (error) {
console.log(error);
}
else {
console.log('SMS sent successfully.');
}
}
);
}
第 2 步:
向用户索要验证码和用户输入的校验码
验证短信方法:
'verifySMS': function (code, userid) {
console.log(userid);
var sms = Meteor.users.findOne({username: userid}).profile.randomSms;
if (sms == code) {
Meteor.users.update({username: userid}, {
$set: {"profile.isMobileVerified": "YES", "profile.randomSms": "--"}
});
return returnSuccess("Yes");
} else {
return returnSuccess("No");
}
},
第 3 步:
从您的 React 代码处理中,如果代码匹配,则批准用户,否则显示适当的错误消息。
更新以处理 OP 的特定用例:
(React 代码示例)
要在每次登录前通过 SMS OTP 代码对用户进行身份验证,您需要在每次用户尝试登录时使用 sendSMS 方法,在存储的 AuthCodes 集合中更新它,每次验证代码,以及相应地处理案件。
反应形式:
您将需要在您的 React JSX 代码容器中呈现类似这样的表单。
<form className="new-task" onSubmit={this.handleSubmit.bind(this)} >
<input
type="text"
ref="phoneNumberInput"
placeholder="Enter Phone Number"
/>
</form>
为登录用户编写 React 函数:
handleSubmit() {
event.preventDefault();
// Find the phone number field via the React ref
const phoneNumber = ReactDOM.findDOMNode(this.refs.phoneNumberInput).value.trim();
Meteor.call('sendAuthCode', Meteor.userId(), phoneNumber, function(error, result) {
// Show a popup to user that code has been sent
});
}
然后,与上面类似,创建另一个表单让用户输入发送给他们的代码,并将其发送到服务器进行验证,例如
handleAuthCheck() {
event.preventDefault();
// Find the phone number field via the React ref
const phoneNumber = ReactDOM.findDOMNode(this.refs.phoneNumberInput).value.trim();
const code = ReactDOM.findDOMNode(this.refs.codeInput).value.trim();
Meteor.call('verifyAuthCode', Meteor.userId(), phoneNumber, code, function(error, result) {
// handle result accordingly
// you need to decide how you are going to login user
// you can create a custom module for that if you need to
});
}
AuthCodes 集合:
您将需要在文件中定义一个集合并将其导出,以便可以在需要的地方导入它。
export const AuthCodes = new Mongo.Collection('authcodes');
Meteor 服务器方法:
发送短信:
'sendAuthCode': function(userId, phoneNumber) {
var min = 10000;
var max = 99999;
var code = Math.floor(Math.random() * (max - min + 1)) + min;
Meteor.call("sendSMS", code, phoneNumber);
AuthCodes.insert({
userId: userId,
phoneNumber: phoneNumber,
code: code
});
}
验证码:
'verifyAuthCode': function(userId, phoneNumber, code) {
var authCode = AuthCodes.findOne({ phoneNumber: phoneNumber, code: code }) // You can also add userId check for added verification
if(typeof authCode !== "undefined" && authCode) {
// verification passed
return true;
} else {
// verification failed
return false;
}
}
我需要在我的 Meteor 应用程序中进行短信验证。
假设我有一个简单的表单(React 风格,因为我在前端使用 React):
<form onSubmit={ this.submitPhone() }>
<input type='text' size='10' placeholder='Your phone here' />
<input type='submit' value='Send me a code'/>
</form>
用户输入他的 phone 号码并提交表格。之后,短信代码将发送到输入的号码。并出现一个新表格:
<form onSubmit={ this.submitCode() }>
<input type='text' size='5' placeholder='Enter code' />
<input type='submit' value='Sign In'/>
</form>
如果用户正确输入了他的代码,那么 Meteor 应该知道用户已登录(我认为是使用一些 _id)。如果代码不正确,则会显示一条错误消息。
我找到了 Twilio 服务和这个 package,它看起来正是我所需要的。但是完全不知道怎么用
我几个月前在教程中只尝试过 Meteor 的默认帐户 UI 身份验证方式,但实际上我不知道如何做这些事情,尤其是通过 SMS。我不需要我的应用程序中的角色之类的东西,我什至不需要用户名、密码和电子邮件。我只需要有一个用户群 _id
和 phone
。所以我只需要让用户能够登录(第一次登录就是用这种方式注册)。
感谢您的帮助,详细的回答正是我这次所需要的。
首先,您需要安装以下软件包之一:
- http(直接从您的方法调用 Twilio API)或者,
- accolver:twilio-meteor (You can try using the services this package provides off of the official Twilio-Node Helper Library)
接下来,您还应该安装 okland:accounts-phone package to help enable login via phone number. Their GitHub 提供简单易懂的设置说明。
密码
我强烈建议使用密码和 phone 号码创建用户帐户,因为它是一个很好的安全功能,并且在 Meteor 帐户包中默认也是必需的。
验证过程
我将给出一个使用服务器端 Meteor 方法 的示例,对于前端,您可以相应地编写 React 处理程序。
此示例将使用 HTTP 包,如果您愿意,可以在您的代码中修改它以包含其他包装器包,如 twilio-meteor。
第一步: 注册您的用户并发送验证短信。
createNewUser 方法:
'createNewUser': function (password, phoneNumber) {
var min = 10000;
var max = 99999;
var random = Math.floor(Math.random() * (max - min + 1)) + min;
var verified = Meteor.users.find({username: phoneNumber}).fetch();
if (verified.length > 0) {
if (verified.length == 1 && verified[0].profile.isMobileVerified == 'NO') {
Meteor.users.remove({username: phoneNumber});
var user = {username: phoneNumber, password: password, profile: { randomSms: random, isMobileVerified: 'NO' }};
Meteor.call("sendSMS", random, phoneNumber);
Accounts.createUser(user);
return returnSuccess('Successfully created', phoneNumber);
} else {
return returnFaliure('Mobile number already exists', phoneNumber);
}
} else {
var user = {username: phoneNumber, password: password, profile: { randomSms: random, isMobileVerified: 'NO' }};
Meteor.call("sendSMS", random, phoneNumber);
Accounts.createUser(user);
return returnSuccess('Successfully created', phoneNumber);
}
},
发送短信方法:
'sendSMS': function (code, mobile) {
console.log(mobile);
HTTP.call(
"POST",
'https://api.twilio.com/{yyyy-dd-mm}/Accounts/' +
'{TWILIO_APPKEY}' + '/SMS/Messages.json', {
params: {
From: '+11234567890',
To: mobile,
Body: "Greetings! Your OTP is " + code
},
auth: '{TWILIO_APPKEY}' + ':' + '{TWILIO_PASSWORD}'
},
// Print error or success to console
function (error) {
if (error) {
console.log(error);
}
else {
console.log('SMS sent successfully.');
}
}
);
}
第 2 步: 向用户索要验证码和用户输入的校验码
验证短信方法:
'verifySMS': function (code, userid) {
console.log(userid);
var sms = Meteor.users.findOne({username: userid}).profile.randomSms;
if (sms == code) {
Meteor.users.update({username: userid}, {
$set: {"profile.isMobileVerified": "YES", "profile.randomSms": "--"}
});
return returnSuccess("Yes");
} else {
return returnSuccess("No");
}
},
第 3 步: 从您的 React 代码处理中,如果代码匹配,则批准用户,否则显示适当的错误消息。
更新以处理 OP 的特定用例: (React 代码示例)
要在每次登录前通过 SMS OTP 代码对用户进行身份验证,您需要在每次用户尝试登录时使用 sendSMS 方法,在存储的 AuthCodes 集合中更新它,每次验证代码,以及相应地处理案件。
反应形式: 您将需要在您的 React JSX 代码容器中呈现类似这样的表单。
<form className="new-task" onSubmit={this.handleSubmit.bind(this)} >
<input
type="text"
ref="phoneNumberInput"
placeholder="Enter Phone Number"
/>
</form>
为登录用户编写 React 函数:
handleSubmit() {
event.preventDefault();
// Find the phone number field via the React ref
const phoneNumber = ReactDOM.findDOMNode(this.refs.phoneNumberInput).value.trim();
Meteor.call('sendAuthCode', Meteor.userId(), phoneNumber, function(error, result) {
// Show a popup to user that code has been sent
});
}
然后,与上面类似,创建另一个表单让用户输入发送给他们的代码,并将其发送到服务器进行验证,例如
handleAuthCheck() {
event.preventDefault();
// Find the phone number field via the React ref
const phoneNumber = ReactDOM.findDOMNode(this.refs.phoneNumberInput).value.trim();
const code = ReactDOM.findDOMNode(this.refs.codeInput).value.trim();
Meteor.call('verifyAuthCode', Meteor.userId(), phoneNumber, code, function(error, result) {
// handle result accordingly
// you need to decide how you are going to login user
// you can create a custom module for that if you need to
});
}
AuthCodes 集合: 您将需要在文件中定义一个集合并将其导出,以便可以在需要的地方导入它。
export const AuthCodes = new Mongo.Collection('authcodes');
Meteor 服务器方法:
发送短信:
'sendAuthCode': function(userId, phoneNumber) {
var min = 10000;
var max = 99999;
var code = Math.floor(Math.random() * (max - min + 1)) + min;
Meteor.call("sendSMS", code, phoneNumber);
AuthCodes.insert({
userId: userId,
phoneNumber: phoneNumber,
code: code
});
}
验证码:
'verifyAuthCode': function(userId, phoneNumber, code) {
var authCode = AuthCodes.findOne({ phoneNumber: phoneNumber, code: code }) // You can also add userId check for added verification
if(typeof authCode !== "undefined" && authCode) {
// verification passed
return true;
} else {
// verification failed
return false;
}
}