如何基于Twilio、Python和Django实现手机号注册的OTP发送机制?
实现Django+Twilio手机号注册的OTP发送流程
我来一步步帮你搞定这个功能,从接收用户手机号到发送OTP的完整逻辑都给你理清楚:
1. 先封装Twilio发送OTP的函数
首先把你现有的Twilio代码封装成一个可复用的函数,让它能接收用户手机号作为参数,这样就能动态填充to参数了。另外,不要把Twilio的account_sid和auth_token硬编码在代码里,用Django的配置或者环境变量更安全:
# 在你的Django项目里新建一个utils.py(或者随便一个工具文件) from twilio.rest import Client import random from django.conf import settings def send_otp(phone_number): # 生成4位OTP otp = random.randint(1000, 9999) try: # 从Django配置里取Twilio的凭证(建议在settings.py里配置) client = Client(settings.TWILIO_ACCOUNT_SID, settings.TWILIO_AUTH_TOKEN) client.messages.create( from_=settings.TWILIO_PHONE_NUMBER, # 你的Twilio号码,带国家码 to=phone_number, # 这里就是用户输入的手机号,要带国家码比如+8613xxxxxxxxx body=f"Your OTP is - {otp}" ) return otp # 返回OTP,后续用来验证 except Exception as e: # 处理发送失败的情况,比如网络问题、Twilio账户问题 print(f"OTP发送失败: {str(e)}") return None
然后在settings.py里添加Twilio的配置:
# settings.py TWILIO_ACCOUNT_SID = "你的Twilio账户SID" TWILIO_AUTH_TOKEN = "你的Twilio授权Token" TWILIO_PHONE_NUMBER = "你的Twilio手机号,格式如+1234567890"
2. 接收用户输入的手机号(Django表单+视图)
接下来需要让用户提交手机号,我们用Django的表单和视图来处理:
第一步:写一个手机号表单(forms.py)
# forms.py from django import forms class PhoneNumberForm(forms.Form): phone_number = forms.CharField( label="手机号", max_length=15, widget=forms.TextInput(attrs={"placeholder": "请输入带国家码的手机号,如+8613xxxxxxxxx"}) ) # 可以加一个验证,确保手机号格式正确 def clean_phone_number(self): phone = self.cleaned_data.get("phone_number") if not phone.startswith("+"): raise forms.ValidationError("请输入带国家码的手机号,比如+86开头") return phone
第二步:写处理请求的视图(views.py)
# views.py from django.shortcuts import render, redirect from .forms import PhoneNumberForm from .utils import send_otp def request_otp(request): if request.method == "POST": form = PhoneNumberForm(request.POST) if form.is_valid(): phone_number = form.cleaned_data["phone_number"] otp = send_otp(phone_number) if otp: # 把OTP和手机号存在session里,后面验证的时候用 request.session["phone_number"] = phone_number request.session["otp"] = otp # 跳转到OTP验证页面 return redirect("verify_otp") else: form.add_error(None, "OTP发送失败,请稍后重试") else: form = PhoneNumberForm() return render(request, "request_otp.html", {"form": form})
3. 写前端模板(request_otp.html)
让用户能输入手机号的页面:
<!-- templates/request_otp.html --> <!DOCTYPE html> <html> <head> <title>获取OTP</title> </head> <body> <h2>输入手机号获取验证码</h2> <form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">发送验证码</button> </form> {% if form.non_field_errors %} <p style="color:red;">{{ form.non_field_errors.0 }}</p> {% endif %} </body> </html>
4. 配置URL路由(urls.py)
把视图映射到URL:
# urls.py from django.urls import path from .views import request_otp urlpatterns = [ path("request-otp/", request_otp, name="request_otp"), # 后面还要加OTP验证的路由,这里先不展开 ]
关键细节提醒
- 手机号格式:Twilio要求
to参数必须带国家码(比如中国手机号是+8613xxxxxxxxx),所以一定要让用户输入正确的格式,或者在后端自动补加国家码(比如判断手机号是国内的就自动加+86)。 - OTP存储:我这里用了session来存OTP和手机号,如果你需要持久化(比如用户关闭浏览器后还能验证),可以存在数据库里(比如建一个OTP模型,关联手机号和过期时间)。
- 错误处理:一定要加异常捕获,比如Twilio调用失败、网络超时等情况,给用户友好的提示。
- 安全问题:OTP要设置过期时间(比如5分钟),避免被恶意利用。
这样整个流程就通了:用户在前端输入手机号→提交到Django视图→视图调用Twilio发送函数→把OTP存起来→跳转到验证页面。
内容的提问来源于stack exchange,提问作者tcma13
相关产品推荐
相关产品推荐

