Twilio Verify是一项易于使用的服务,通过数字代码进行用户验证。这项服务现在包括对WhatsApp的支持(截至2022年6月,处于公开测试阶段)。在本教程中,你将学习如何在Python和Flask应用程序中实现WhatsApp用户验证流程。
要求
要完成本教程,你需要以下物品。
- Python 3.6或更新版本。如果你的操作系统没有提供Python解释器,你可以去python.org下载一个安装程序。
- 一个Twilio账户。如果你是Twilio的新手,请点击这里,现在就可以创建一个免费账户,当你升级到付费账户时,可以获得10美元的积分。你可以查看免费Twilio账户的功能和限制。
- 一个活跃的WhatsApp账户,用来测试项目。
创建一个Twilio Verify服务
要在一个应用程序中使用Twilio Verify,必须先创建一个Verify服务。在你的网页浏览器中打开Twilio控制台,在导航栏的搜索框中输入verify,并在搜索结果中选择 "Verify服务"。
在验证服务页面,点击 "立即创建服务 "按钮。
如果你的账户中已经有一个或多个Verify服务,那么这个按钮将在服务列表的顶部显示为一个加号。
在 "友好名称 "栏中输入你的应用程序的名称。在本教程中,我将使用 "Awesome App "的名称。你在这个字段中输入的名字将出现在发送给用户的WhatsApp验证信息中。一旦你输入了名字,按 "创建"。
一旦服务被创建,您将被重定向到其设置页面。在您继续学习本教程时,请打开该页面,因为您以后将需要分配给您的服务的 "服务SID"。
在本教程中,服务的默认设置是合适的,但请注意你如何配置,除其他外,在发送给用户的验证码中使用多少个数字。
项目设置
在本节中,你将设置一个全新的Flask项目。为了使事情井井有条,请打开终端或命令提示符,找到一个合适的父目录,将你将要创建的项目放在那里。输入以下命令,为这个项目创建一个目录。
mkdir flask-whatsapp-verify
cd flask-whatsapp-verify
这个应用程序将需要一些HTML模板。在该项目中为它们创建一个目录。
mkdir templates
创建一个虚拟环境
按照Python的最佳实践,你现在要创建一个虚拟环境,在那里安装本项目所需的Python依赖项。
如果你使用的是 UNIX 或 macOS 系统,打开一个终端,输入以下命令。
python3 -m venv venv
source venv/bin/activate
如果你在Windows上学习本教程,在命令提示符窗口中输入以下命令。
python -m venv venv
venv\Scripts\activate
激活了虚拟环境后,就可以安装本项目所需的 Python 依赖项了。
pip install flask python-dotenv twilio
本项目使用的Python包是。
- Flask框架,用于创建Web应用程序。
- python-dotenv,从*.env*文件中导入应用配置。
- Twilio Python Helper库,用于与Twilio APIs协同工作。
定义应用程序的设置
为了用Twilio Verify发送验证信息,Flask应用程序需要用你的Twilio账户凭证进行验证。该应用程序还需要知道分配给你上面创建的Verify服务的 "服务SID"。
定义这些配置值的最安全的方法是为它们设置环境变量,而在Flask应用程序中管理环境变量的最方便的方法是使用*.env*文件。
在你项目的根目录下创建一个名为*.env*的新文件(注意前面的点),并在其中输入以下内容。
TWILIO_ACCOUNT_SID=xxxxxxxxx
TWILIO_AUTH_TOKEN=xxxxxxxxx
TWILIO_VERIFY_SERVICE=xxxxxxxxx
你需要把所有的xxxxxxxxx
占位符替换成适用于你的正确值。前两个变量是你的Twilio "账户SID "和你的 "Auth Token"。你可以在Twilio Console主仪表板的 "账户信息 "部分找到它们。
第三个配置变量的值来自验证服务页面的 "服务SID "字段。这是一长串以字母VA
开始的字符。
发送一个验证码
现在你已经准备好开始对 Python 应用程序进行编码。在你的文本编辑器或IDE中,在项目的根目录下创建一个名为app.py的文件。将以下内容复制到其中。
import os
from flask import Flask, render_template, request, session, redirect, url_for
from twilio.rest import Client
app = Flask(__name__)
app.config['SECRET_KEY'] = 'top-secret!'
client = Client()
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'GET':
return render_template('index.html')
phone = request.form.get('phone')
if not phone:
return redirect(url_for('index'))
verification = client.verify.services(
os.environ['TWILIO_VERIFY_SERVICE']).verifications.create(
to=phone, channel='whatsapp')
if verification.status != 'pending':
return redirect(url_for('index'))
session['phone'] = phone
return redirect(url_for('verify'))
该应用程序创建了两个全局对象:Flask应用程序和Twilio客户端实例。Flask应用程序实例被配置了一个密匙,因为这需要访问会话存储。
Twilio客户端被隐含地初始化为环境中定义的TWILIO_ACCOUNT_SID
和TWILIO_AUTH_TOKEN
变量。如果这些变量没有定义或不正确,在使用应用程序时将出现认证错误信息。
index()
函数是应用程序的根URL的处理程序。这个路由支持GET
和POST
方法。GET
请求将呈现一个网页表单,用户可以在其中输入他们的WhatsApp电话号码。然后,当用户提交表单时,浏览器将向同一URL发送一个POST
请求。
当请求方法是GET
,应用程序会渲染一个名为index.html的模板。在templates子目录下创建index.html文件,并将以下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>
这个HTML页面渲染了一个表单,提示用户输入他们的WhatsApp电话号码。
当用户提交表格时,浏览器将发送一个POST
请求到同一个URL。在这一点上,应用程序将从Flask框架提供的request.form
对象中获取电话号码。如果电话号码不存在,就会发出一个重定向到索引页,给用户另一个机会输入正确的信息。
然后,Twilio客户端被用来创建一个verification
实例,用用户的电话号码初始化,通道设置为whatsapp
。这将触发Twilio生成的验证码,并通过WhatsApp发送至用户提供的号码。
然后应用程序检查验证实例上的报告状态。如果状态不是pending
,就会认为发生了错误,然后用户会被重定向到主页面。
对于一个待定的验证,电话号码被存储在用户的会话中,然后用户被重定向到*/verify*URL,这就是请求验证码的地方。
验证码
一旦用户提供了一个电话号码并发出了一个验证码,应用程序的*/验证*页面允许用户输入他们通过WhatsApp收到的代码。
下面你可以看到应用程序的验证路线。在app.py的底部添加这段代码。
@app.route('/verify', methods=['GET', 'POST'])
def verify():
if request.method == 'GET':
return render_template('verify.html')
phone = session.get('phone')
code = request.form.get('code')
if not phone:
return redirect(url_for('index'))
if not code:
return redirect(url_for('verify'))
verification_check = client.verify.services(
os.environ['TWILIO_VERIFY_SERVICE']).verification_checks.create(
to=phone, code=code)
if verification_check.status == 'approved':
del session['phone']
return redirect(url_for('success'))
return redirect(url_for('verify'))
这个路由也支持GET
和POST
请求。在GET
的情况下,它渲染一个名为verify.html的模板。在你的编辑器中,在模板子目录下打开一个名为verify.html的新文件,并复制以下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>
在verify.html中定义的表单要求用户提供一个代码。当表单被提交时,一个POST
的请求被发送到同一个URL。
应用程序从会话存储中检索phone
参数和随表单提交的code
参数,并将它们发送给 Twilio Verify 以创建一个验证检查实例。如果代码对给定的号码是正确的,那么验证检查的状态是approved
。在这种情况下,电话号码从会话中删除,然后用户被重定向到*/successURL上的应用程序的第三个也是最后一个路径。如果状态是任何其他的值,那么验证就失败了,用户会被重定向到/verify*路线,尝试另一个代码。
下面,你可以看到*/success路由的定义。把这段代码复制到app.py*的底部。
@app.route('/success')
def success():
return render_template('success.html')
这个路由除了渲染一个success.html模板外,不需要任何逻辑。这个HTML模板如下图所示。记住,模板文件要放在templates子目录下。
<!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.py文件在项目的根目录下,并且你的templates子目录中有index.html、verify.html和success.html文件。
在你的终端输入以下命令来启动应用程序。
flask run
一旦应用程序启动,打开您的网络浏览器并导航到*http://localhost:5000。*以E.164格式键入你的WhatsApp电话号码,以请求一个验证码。
几秒钟后,您应该在WhatsApp上收到一条带有您的代码的信息。在应用程序的验证页面中输入这个代码,就会收到一个成功的消息。此外,请随时尝试一个错误的代码,看看它是如何被拒绝的,你会得到另一个机会。
结论
恭喜你学会了如何用Twilio Verify验证WhatsApp上的用户!你知道Twilio Verify也可以通过短信、语音电话和电子邮件向用户发送验证码吗?它还可以验证标准的TOTP代码和推送通知到你的iOS或Android应用程序
我很想看看你用Twilio Verify建立了什么!
*Miguel Grinberg*是Twilio的技术内容首席软件工程师。与他联系的方式是 mgrinberg *[at] twilio [dot] com联系他。*如果你有一个很酷的项目想在这个博客上分享,请联系他。