You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:20:17