Twilio Verify是一项易于使用的用户验证服务。这项服务现在包括对WhatsApp一次性密码的支持(截至2022年6月,处于公开测试阶段)。在本教程中,你将学习如何使用Node.js和Express在一个JavaScript应用程序中实现WhatsApp用户验证流程。

要求
要完成本教程,你需要以下物品。
- 在你的机器上安装Node.js。
- 一个Twilio账户。如果你是Twilio的新手,请点击这里,现在就可以创建一个免费账户,当你升级到付费账户时,可以获得10美元的积分。你可以查看免费Twilio账户的功能和限制。
- 一个活跃的WhatsApp账户,用来测试项目。
创建一个Twilio Verify服务
要在一个应用程序中使用Twilio Verify,必须先创建一个Verify服务。在你的网页浏览器中打开Twilio控制台,在导航栏的搜索框中输入verify,并在搜索结果中选择 "Verify服务"。

在Verify服务页面,点击 "立即创建服务 "按钮。
如果你的账户中已经有一个或多个Verify服务,那么这个按钮将在服务列表的顶部显示为一个加号。
在 "友好名称 "栏中输入你的应用程序的名称。在本教程中,我将使用 "Awesome App "的名称。你在这个字段中输入的名字将出现在发送给用户的WhatsApp验证信息中。一旦你输入了名字,按 "创建"。

一旦服务被创建,您将被重定向到其设置页面。在您继续学习本教程时,请打开该页面,因为您以后将需要分配给您的服务的 "服务SID"。
在本教程中,服务的默认设置是适当的,但请注意你如何配置,除其他事项外,在发送给用户的验证码中使用多少位数。
项目设置
在本节中,你将设置一个全新的Express项目。为了使事情井井有条,打开终端或命令提示符,找到一个合适的父目录,你将要创建的项目就在这个目录中。输入以下命令,为这个项目创建一个目录。
mkdir express-whatsapp-verify
cd express-whatsapp-verify
这个应用程序将需要一些HTML页面。在该项目中为它们创建一个公共目录。
mkdir public
接下来安装这个项目所需的依赖项。
npm init -y
npm install express express-session dotenv twilio
这个项目使用的依赖项是。
- Express.js框架,用于创建网络应用。
- Express的会话中间件,用于维护用户会话。
- dotenv包,用于从*.env*文件中导入应用配置。
- Twilio Node Helper库,用于与Twilio APIs一起工作。
为了完成项目的初始设置,在你的文本编辑器或IDE中创建一个名为app.js的文件,并将下面显示的Express应用程序的骨架复制到其中。
require('dotenv').config()
const express = require('express');
const session = require('express-session');
const path = require('path');
const app = express();
const port = 3000;
const sessionOptions = {
secret: 'top-secret!',
resave: false,
saveUninitialized: true,
cookie: {}
}
if (app.get('env') === 'production') {
app.set('trust proxy', 1);
sesssionOptions.cookie.secure = true;
}
app.use(session(sessionOptions));
app.use(express.urlencoded({ extended: false }));
const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const client = require('twilio')(accountSid, authToken);
// application routes will be defined here
app.listen(port, () => {
console.log(`Listening on port ${port}`)
});
这个Express启动程序首先从一个*.env文件(你将在下一节创建)中读取配置变量。然后,它创建了一个应用程序实例,并对其进行了配置,以支持用户会话、从公共子目录中提供的静态文件(默认为.html*扩展名)以及带有 URL 编码字段的表单提交。
然后创建一个Twilio客户端实例,并从*.env*文件中导入凭证,dotenv 包将其添加到process.env 对象中。
该应用程序还没有定义任何路由,但它在3000端口启动了一个Web服务器。
定义应用程序的设置
为了用Twilio Verify发送验证信息,Express应用程序将需要用你的Twilio账户凭证进行验证。该应用程序还需要知道分配给你上面创建的Verify服务的 "服务SID"。
定义这些配置值的最安全方式是为它们设置环境变量,而在 Express 应用程序中管理环境变量的最方便方式是使用*.env*文件。
在你的文本编辑器中创建一个名为*.env*的新文件(注意前面的点),并在其中输入以下内容。
TWILIO_ACCOUNT_SID=xxxxxxxxx
TWILIO_AUTH_TOKEN=xxxxxxxxx
TWILIO_VERIFY_SERVICE=xxxxxxxxx
你将需要用适用于你的正确值来替换所有的xxxxxxxxx 占位符。前两个变量是你的Twilio "账户SID "和 "Auth Token"。你可以在Twilio Console主仪表板的 "账户信息 "部分找到它们。

第三个配置变量的值来自验证服务页面的 "服务SID "字段。这是一长串以字母VA 开始的字符。
发送一个验证码
现在你已经准备好开始编码Node.js应用程序了。当用户用网络浏览器连接到服务器时,Express应用程序需要渲染一个页面,要求用户提供他们的WhatsApp手机号码。
打开一个名为index.html的新文件,位于public子目录下。复制下面的HTML页面到这个文件。
<!doctype html>
<html>
<head>
<title>Twilio WhatsApp Verification Example</title>
</head>
<body>
<h1>Twilio WhatsApp Verification Example</h1>
<form method="post">
<label for="phone">Your WhatsApp number:</label>
<input name="phone" id="phone" placeholder="+12345678900" autofocus>
<input type="submit" value="Submit">
</form>
</body>
</html>
为了向浏览器提供这个页面,让我们向Express应用程序添加第一个路由。在编辑器中打开app.js,并在listen() 调用的正上方写下以下代码。
app.get('/', (req, res) => {
req.session.verified = false;
res.sendFile(path.join(__dirname, 'public/index.html'));
});
这个路由开始时,会重置用户会话中的verified 变量。然后,它向客户端提供你在上面创建的HTML页面。
这个HTML页面渲染了一个有一个字段的表单,用户必须在那里输入他们的WhatsApp电话号码。当用户提交表单时,浏览器将发送一个POST 请求到应用程序的同一根URL。 你现在要为这个POST 请求编码一个处理程序。
在app.js中,在前一个路由之后,仍在listen() 的调用之前,添加以下路由定义。
app.post('/', async (req, res) => {
const verification = await client.verify.services(process.env.TWILIO_VERIFY_SERVICE)
.verifications
.create({to: req.body.phone, channel: 'whatsapp'});
if (verification.status !== 'pending') {
res.redirect('/');
}
else {
req.session.phone = req.body.phone;
res.redirect('/verify');
}
});
处理表单提交的路由是用app.post 。在这里,Twilio客户端被用来创建一个与之前创建的Twilio验证服务相关的verification 实例,该实例由TWILO_VERIFY_SERVICE 环境变量引用。这个实例用用户的电话号码和一个设置为whatsapp 的通道进行初始化。电话号码是从req.body 对象中检索的,其中Express.js提供了提交的表单字段。当验证实例被创建时,Twilio将通过WhatsApp向用户提供的号码发出一个验证码。
然后应用程序检查验证对象上的报告状态。如果状态不是pending ,则认为发生了错误,用户会被重定向到主页面再试一次。
对于一个待定的验证,用户会被重定向到*/verify*URL,这就是要求验证码的地方。在重定向之前,用户提供的电话号码会被保存到用户会话中,以便在验证时可以使用。
验证代码
一旦用户提供了电话号码并发出了验证码,应用程序的*/verify*URL允许用户输入通过WhatsApp收到的代码。
下面你可以看到这个页面的HTML。将该HTML复制到公共子目录下一个名为verify.html的文件。
<!doctype html>
<html>
<head>
<title>Twilio WhatsApp Verification Example</title>
</head>
<body>
<h1>Twilio WhatsApp Verification Example</h1>
<form method="post">
<label for="code">Verification code:</label>
<input name="code" id="code" placeholder="123456" autofocus>
<input type="submit" value="Submit">
</form>
</body>
</html>
为了向客户端提供这个页面,在app.js中添加一个*/verify*路由。你可以在前面两个路由之后直接添加这个路由。
app.get('/verify', (req, res) => {
res.sendFile(path.join(__dirname, 'public/verify.html'));
});
这个页面中定义的表单向用户请求一个代码。当表单被提交后,一个带有输入信息的POST 请求被发送到同一个*/verify*URL。
下面你可以看到处理这第二个表单的提交的路由。将代码添加到app.js中,就在前面的路由定义之后。
app.post('/verify', async (req, res) => {
const phone = req.session.phone;
const code = req.body.code;
if (!phone) {
res.redirect('/');
}
else if (!code) {
res.redirect('/verify');
}
else {
const verificationCheck = await client.verify.services(process.env.TWILIO_VERIFY_SERVICE)
.verificationChecks
.create({to: phone, code: code});
if (verificationCheck.status === 'approved') {
req.session.phone = undefined;
req.session.verified = true;
res.redirect('/success');
}
else {
res.redirect('/verify');
}
}
});
应用程序从会话存储中检索phone 参数,以及与表单一起提交的code 参数。如果这两个参数都不存在,用户就会被重定向离开这个页面,因为没有这两个值就不可能进行验证。然后,这些信息被发送到Twilio Verify,以创建一个验证检查实例。
验证检查对象中的status 属性告诉我们,验证是否成功。如果代码对于给定的号码是正确的,那么验证检查的状态是approved 。在这种情况下,verified 会话变量被设置为true ,用户被重定向到第三个也是最后一个页面*/successURL。如果状态不是approved ,那么验证就失败了,用户会被重定向到/verify*路线,尝试另一个代码。
/success路线也由一个HTML页面支持。创建一个名为public/success.html的文件并在其中输入以下代码。
<!doctype html>
<html>
<head>
<title>Twilio WhatsApp Verification Example</title>
</head>
<body>
<h1>Twilio WhatsApp Verification Example</h1>
<p>You have been verified!</p>
<p><a href="/">Verify another number?</a></p>
</body>
</html>
这个页面显示一个成功信息,并提供一个链接到第一页,以备用户想做另一个验证。为了服务这个页面,在app.js中添加*/success*路由。
app.get('/success', (req, res) => {
if (!req.session.verified) {
res.redirect('/');
}
else {
res.sendFile(path.join(__dirname, 'public/success.html'));
}
});
这个最终路由中的逻辑会检查verified 会话变量是否为true ,在这种情况下,它会将verify.html文件渲染到客户端。如果由于任何原因,用户在到达这个路由时没有被验证,他们会被重定向到初始页面,开始验证过程。
运行应用程序
该应用程序现在已经完成。通过在你的终端输入以下命令来启动它。
node app.js
一旦应用程序启动,打开你的网络浏览器并导航到*http://localhost:3000。*以E.164格式键入你的电话号码,要求提供验证码。为了简单起见,这个字段被实现为一个普通的文本字段。如果你有兴趣为你的网络应用程序实现一个全功能的电话输入字段,你可以看看这个教程。
几秒钟后,你应该在WhatsApp上收到一条带有你的代码的传入信息。在应用程序的验证页面中输入这个代码,就可以收到一个成功的消息。也可以随意尝试一个错误的代码,看看它是如何被拒绝的,并为你提供另一个机会。
总结
恭喜你学会了如何用Twilio Verify在WhatsApp上验证用户!你知道Twilio Verify也可以通过短信、语音电话、电子邮件向用户发送验证码吗?它还可以验证标准的TOTP代码和推送通知到你的iOS或Android应用程序
我很想看看你用Twilio Verify建立了什么!