2016-08-17 113 views
3

我需要在我的Meteor应用程序中进行短信认证。在流星中通过短信登录并注册过程

比方说,我有一个简单的表格(在阵营风格,因为我使用的前端反应):

<form onSubmit={ this.submitPhone() }> 
    <input type='text' size='10' placeholder='Your phone here' /> 
    <input type='submit' value='Send me a code'/> 
</form> 

用户输入自己的电话号码并提交表单。之后,短信代码被发送到输入的号码。并出现了新的形式:

<form onSubmit={ this.submitCode() }> 
    <input type='text' size='5' placeholder='Enter code' /> 
    <input type='submit' value='Sign In'/> 
</form> 

如果用户正确输入自己的密码,然后流星应该知道用户登录(与一些_id,我认为)。如果代码不正确,则显示错误消息。

我发现Twilio服务和这package,它看起来正是我所需要的。但我根本不知道如何使用它。

几个月前我在教程中只尝试过Meteor的默认帐户UI认证方式,但实际上我不知道如何做这些事情,特别是通过SMS。我不需要像我的应用程序中的角色这样的东西,我甚至不需要用户名,密码和电子邮件。我只需要有一个用户基地_idphone。所以我需要的是让用户能够登录(首次登录是这样注册的)。

感谢您的帮助,详细的答案真的是我这次需要的。

回答

4

首先,您需要安装以下的包之一:

接下来,你还应该安装okland:accounts-phone包,以帮助通过电话号码启用登录。他们的GitHub提供了易于遵循如何设置它的指示。

密码

我会强烈建议用密码创建用户帐户,与电话号码一起,因为它是一个很好的安全功能有,并且还需要在默认情况下流星帐户包。

验证过程

我会用服务器端流星方法是给一个例子,对于前端可以编写相应的处理程序作出反应。

这个例子将使用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方法:

'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方法:

'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: 从你阵营码处理,如果码匹配,批准用户,否则显示适当的错误消息。


更新通过OP来处理特定的使用案例: (例指示作出反应代码)

让用户通过登录之前SMS OTP代码每次验证,您将需要使用sendSMS方法,每次用户尝试登录时,都会在存储的AuthCodes集合中更新它,每次验证代码并相应地处理大小写。

反应表格: 您需要在反应的JSX代码容器中呈现类似这样的表单。

<form className="new-task" onSubmit={this.handleSubmit.bind(this)} > 
    <input 
     type="text" 
     ref="phoneNumberInput" 
     placeholder="Enter Phone Number" 
    /> 
</form> 

写入阵营功能登录用户:

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'); 

流星服务器的方法:

发送短信:

'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; 
    } 
} 
+0

感谢您的回答!如果我正确理解你的代码,我认为这不是我正在寻找的东西。这个方法为我提供了一种方法:1)用PhoneNumber,Password和boolean字段isVerified创建一个用户。通过这些方法,我可以验证用户的号码是否唯一一次 - 当此用户有isVerified = false时。之后,用户只能通过他的电话和密码登录我的网站。对不起,如果我不明白的话。但是我需要每次用户想要登录时发送短信 - >验证代码 - >用户登录。我该如何实现? –

+0

okland/accounts-phone让我有一种方法来创建一个电话号码和密码的用户,然后验证其号码一次(第一次),然后该用户必须通过其电话和密码登录。但我需要每次都通过新的短信代码登录。感谢您的帮助! –

+1

在这种情况下,您可以每次用户尝试登录时使用sendSMS方法,在存储的randomNumbers集合中更新它,每次验证代码并相应地处理大小写。这是否满足用例? – ryder