我需要在我的 Meteor 应用程序中进行 SMS 身份验证。
假设我有一个简单的表单(采用 React 风格,因为我在前端使用 React):
<form onSubmit={ this.submitPhone() }>
<input type='text' size='10' placeholder='Your phone here' />
<input type='submit' value='Send me a code'/>
</form>
用户输入他的电话号码并提交表单。然后将 SMS 代码发送到输入的号码。并且出现了一个新表格:
<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
.所以我需要的只是让用户能够登录(第一次登录就是这样注册)。感谢您的帮助,详细的答案正是我这次所需要的。
最佳答案
首先,您需要安装以下软件包之一:
接下来,您还应该安装 okland:accounts-phone 包以帮助启用通过电话号码登录。他们的 GitHub 提供了易于遵循的设置说明。
密码
我强烈建议使用密码和电话号码创建用户帐户,因为这是一个很好的安全功能,并且默认情况下也是 Meteor Accounts 包所必需的。
验证过程
我将给出一个使用服务器端 Meteor 方法的示例,对于前端,您可以相应地编写您的 React 处理程序。
此示例将使用 HTTP 包,如果您愿意,您可以在代码中修改它以包含其他包装器包,如 twilio-meteor。
第 1 步:
注册您的用户并发送验证短信。
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 形式:
您需要在 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;
}
}
关于authentication - 在 Meteor 中通过 SMS 登录和注册过程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38988074/