使用PHP和Twilio多因素身份验证

362576256 2012-12-10 11:00:56
从PHP的使用Twilio

连接到Twilio服务是一样容易Services_Twilio类包括twilio PHP库,并创建一个新的实例。对象的构造函数接受您的帐户的SID和Twilio帐户的仪表板页面上列出的身份验证后,你注册他们的服务令牌。
随着可用Services_Twilio在您的处置实例,你可以访问他们的API,虽然帐户属性。账户公开的的的实例Services_Twilio_Rest_Account代表Twilio帐户。我只使用一个帐户,但它可能有多个子帐户。根据您的需要分割的互动,这可能是有用的。你可以学到更多的子账户,通过阅读Twilio文档。
<?php
require "Services/Twilio.php";

define("TWILIO_SID", "…");
define("TWILIO_AUTH_TOKEN", "…");

$twilio = new Services_Twilio(TWILIO_SID, TWILIO_AUTH_TOKEN);
$acct = $twilio->account;

帐户的实例公开其他几个属性,其中来电和sms_messages的。这些封装其余分别用来发出您的来电和信息资源的Services_Twilio_Rest_Calls和Services_Twilio_Rest_SmsMessages像对象的实例。然而,你很少使用这些对象超出了他们的create()方法,该文件是指,揭露他们作为“实例资源的属性。”我会做同样的,以避免任何混淆。
发送短信

发送短信是通过SMS消息实例资源的create()方法($会计-> sms_messages的)。该方法需要3参数:您的帐户Twilio数量(类似于到了“从地址”的电子邮件),收件人的数量(在“以解决”),和您的消息的文本(它可以是多达160个字符)。

1 <?php
2 $code = "1234"; // some random auth code
3
4 $msg = $acct->sms_messages->create(
5 "+19585550199", // "from" number
6 "+19588675309", // "to" number
7 "Your access code is " . $code
8 );

尾巴 ​​的场景,的twilio PHP库问题的一些代表您TwiML POST请求的Twilio API。一个实例Services_Twilio_Rest_SmsMessage的返回呼叫,它封装了有关消息的信息。你可以看到一个什么样的信息提供的文档中的完整列表,但可能是更重要的价值是由暴露的地位和价格属性。状态显示SMS消息(要么排队,发送,发送,或失败)的状态,价格揭示消息到您的帐户结算的金额。
发送语音通话

发起语音呼叫是通过创建()方法的调用实例资源(ACCT->通话)。如发送SMS消息,您需要提供您的帐户号码,收件人的电话号码,和消息。然而,在这种情况下,消息到TwiML的文件,介绍了呼叫的性质是一个网址。

01 <?php
02 // Note spaces between each letter in auth code. This forces
03 // the speech synthesizer to enunciate each digit.
04 $code = "1 2 3 4";
05
06 $msg = $acct->calls->create(
07 "+19585550199", // "from" number
08 "+19588675309", // "to" number
09 "http://example.com/voiceCall.php?code=" . urlencode($code)
10 );

再次库问题上代表您的POST请求和语音通话。当被叫方接听她的电话,Twilio的进程检索并执行回调URL的XML提供的命令。在上面的示例,发起语音呼叫,我通过在URL GET参数的回调脚本的确认代码。Twilio检索URL时,PHP将呈现响应时使用的参数。
目前只有少数TwiML标签,你需要兴建呼叫流程,但你可以用它们来定义流量是相当复杂的(如电话树菜单等)。一个基本呼叫流程,这种类型的场景,虽然可以产生PHP和看起来像这样:

01 <?php
02 header("Content-Type: text/xml");
03 $code = isset($_GET["code"]) ? htmlspecialchars($_GET["code"]) : null;
04 $digit = isset($_POST["Digits"]) ? (int)$_POST["Digits"] : null;
05 $url = htmlspecialchars($_SERVER["PHP_SELF"]) . "?code=" . $code;
06
07 echo '<?xml version="1.0" encoding="UTF-8"?>';
08 ?>
09 <Response>
10 <?php
11 if (is_null($code)) {
12 ?>
13 <Say>Sorry. An error occurred.</Say>
14 <?php
15 }
16 else {
17 ?>
18 <Gather action="<?php echo $url; ?>" numDigits="1">
19 <?php
20 if (is_null($digit) || $digit == 1) {
21 ?>
22 <Say>Your access code is <?php echo $code; ?></Say>
23 <?php
24 }
25 ?>
26 <Say>Press 1 to repeat the code.</Say>
27 </Gather>
28 <?php
29 }
30 ?>
31 <Say>Good bye.</Say>
32 </Response>
这里使用的TwiML标签响应(根元素),说(提供文本将由Twilio发言),收集(收集来自用户的输入)。
虽然说孩子说文字元素,Twilio也将被监听,因为用户输入收集,暂停5秒后,提供一个窗口,用户输入她的反应。如果收集超时没有输入,退出,并执行后续的言论,文字和终止呼叫。否则,输入被调回的行动进一步处理URL。
Twilio文档收集非常好解释的行为和元素的属性,你可以用它来 ​​修改行为,甚至列出了几个样品。我建议你给它一个快速读取。
还有一个值得注意的最后一件事,在移动之前,我已经添加了彼此之间在启动脚本中的认证码的数字空间。这迫使每个数字语音合成阐明说:“一二三四”,而不是“一万二一百三十四。”随着语音合成,有时我们在文本中看到的不一定是我们所得到的。没关系捏造或拼错的语音对话,如果它导致更好的清晰度和理解你被调用。
实施多因子认证
现在你明白与Twilio的短信和语音交互的基本工作流程,这一次看到它适合的登录过程。你可以在这里看到的是相当平直向前,为清晰起见,我已经减少附带的代码,因为你自己的登录过程的详情,将不可避免地有所不同。
用户应提交登录表单启动过程。表单提交导致您核实她的凭据,并拒绝他们,如果他们是坏的,但有效的凭证,不应该立即验证您的应用程序的用户。相反,考虑用户“部分验证”,国家允许她查看第二种形式请求已发送到她的电话代码。只后,她提交了正确的代码应该授权用户。

001 <?php
002 session_start();
003
004 require "Services/Twilio.php";
005
006 define("TWILIO_SID", "…");
007 define("TWILIO_AUTH_TOKEN", "…");
008 define("TWILIO_FROM_NUMBER", "+19585550199");
009 define("TWILIO_VOICE_URL", "http://example.com/voiceCall.php");
010
011 define("DB_HOST", "localhost");
012 define("DB_DBNAME", "test");
013 define("DB_USER", "dbuser");
014 define("DB_PASSWORD", "dbpassword");
015
016 define("CRYPT_SALT", '$2a$07$R.gJb2U2N.FmZ4hPp1y2CN');
017
018 define("AUTH_CODE_LENGTH", 4);
019
020 $db = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_DBNAME,
021 DB_USER, DB_PASSWORD);
022 $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
023
024 if ($_SERVER["REQUEST_METHOD"] == "POST") {
025 // first stage of authentication
026 if (empty($_SESSION["username"])) {
027 $username = isset($_POST["username"])
028 ? $_POST["username"] : "";
029 $password = isset($_POST["password"])
030 ? crypt($_POST["password"], CRYPT_SALT) : "";
031
032 $query = sprintf("SELECT username, phone_number, code_pref FROM users WHERE username = %s AND password = %s",
033 $db->quote($username),
034 $db->quote($password));
035 $result = $db->query($query);
036 $row = $result->fetch(PDO::FETCH_ASSOC);
037 $result->closeCursor();
038
039 // invalid username/password provided
040 if (!$row) {
041 session_unset();
042 }
043 // valid username/password
044 else {
045 $_SESSION["isAuthenticated"] = false;
046 $_SESSION["username"] = $row["username"];
047
048 // generate and send auth code
049 $code = "";
050 for ($i = 0; $i < AUTH_CODE_LENGTH; $i++) {
051 $code .= rand(0, 9);
052 }
053
054 $twilio = new Services_Twilio(TWILIO_SID, TWILIO_AUTH_TOKEN);
055 $acct = $twilio->account;
056
057 // send code via voice or SMS depending on
058 // the user's preference
059 if ($row["code_pref"] == "voice") {
060 // add spaces to force enunciation
061 $tmpCode = join(" ", string_split($code));
062 $msg = $acct->calls->create(
063 TWILIO_FROM_NUMBER,
064 $_row["phone_number"],
065 TWILIO_VOICE_URL . "?code=" .
066 urlencode($tmpCode)
067 );
068 }
069 else {
070 $msg = $acct->sms_messages->create(
071 TWILIO_FROM_NUMBER,
072 $_row["phone_number"],
073 "Your access code is " . $code
074 );
075 }
076
077 // "remember" code in session
078 $_SESSION["code"] = $code;
079 }
080 }
081 // second stage authentication
082 else {
083 $code = isset($_POST["code"]) ? $_POST["code"] : "";
084 if ($code == $_SESSION["code"]) {
085 $_SESSION["isAuthenticated"] = true;
086 unset($_SESSION["code"]);
087 }
088 }
089 }
090
091 if (!empty($_SESSION["isAuthenticated"])) {
092 ?>
093 <h1>W00t! You're Authenticated!</h1>
094 <?php
095 }
096 // present login forms
097 else {
098 if (empty($_SESSION["username"])) {
099 ?>
100 <h1>Login Step 1</h1>
101 <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
102 <input type="text" name="username">
103 <input type="password" name="password">
104 <input type="submit" value="Login">
105 </form>
106 <?php
107 }
108 else {
109 ?>
110 <h1>Login Step 2</h1>
111 <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
112 <input type="text" name="code">
113 <input type="submit" value="Confirm">
114 </form>
115 <?php
116 }
117 }

上面的代码只是说明。在你的真实世界的应用程序,你可能要考虑增加以下:
添加一个链接到用户的手机重新确认代码。
取消链接添加代码申请表的情况下,用户决定不再继续与过程。与上面的代码,这样的链接需要取消设置了$ _SESSION [“username”的值以来,除了存储用户名,也充当“部分认证”标志$ _SESSION中[“isAuthenticated的”]。
如果已经提供了一个不正确的代码,添加限制或帐户锁定。
根据你的偏执或您所面临的合规性要求,登录身份验证事件的地方。(通常是一个多因素身份验证的应用程序,这需要足够敏感,以保证审计线索!)
此外,您可能要投入一些想法,你的目的创造足够复杂的验证码。4位数字代码是很常见的,但你不仅限于这一点。如果您选择使用字母或字母数字值的组合,我建议避免值,可以很容易混淆(如数字0与字母O,1号与信我,等)。
总结
经济实惠的移动设备和IP电话的扩散增加了额外的渠道,与用户进行交互,在这篇文章中,你学习的一种方式利用这些渠道,通过实施多因素身份验证,使用“云通信”服务Twilio。
我希望你们已经发现这篇文章有助于了解多因素身份验证和Twilio。随意发表评论,下面分享你如何使用Twilio或在自己的应用程序实现多因素身份验证。我很乐意听到这个消息!

...全文
204 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

21,886

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧