TypechoJoeTheme

至尊技术网

登录
用户名
密码

Django商城项目实战08:注册界面短信验证码功能实现全解析

2025-12-12
/
0 评论
/
2 阅读
/
正在检测是否收录...
12/12

正文:

在电商系统的用户注册流程中,短信验证码已成为标配的安全验证手段。今天我们就来深度剖析如何在Django商城项目中实现一套完整的短信验证码功能。

一、技术方案设计

  1. 整体流程



    • 用户点击获取验证码按钮
    • 前端发送AJAX请求到后端
    • 后端生成随机验证码并存入Redis
    • 调用短信平台API发送验证码
    • 用户提交表单时验证码校验
  2. 技术选型



    • 短信平台:云片API(性价比高,文档完善)
    • 缓存系统:Redis(高性能,自动过期)
    • 异步任务:Celery(可选,提升用户体验)

二、云片API配置

首先需要在云片官网注册账号并获取API_KEY:

# settings.py
YP_API_KEY = "your_api_key_here"
YP_SIGN = "【愚公商城】"  # 审核通过的签名

三、后端核心实现

  1. 验证码生成工具类
# utils/sms.py
import random
import redis
from django.conf import settings

def generate_code(length=6):
    """生成指定位数的数字验证码"""
    return ''.join(random.choice('0123456789') for _ in range(length))

class SMSUtil:
    def __init__(self):
        self.redis = redis.StrictRedis(
            host=settings.REDIS_HOST,
            port=settings.REDIS_PORT,
            db=settings.REDIS_DB
        )
    
    def save_code(self, phone, code, expire=300):
        """保存验证码到Redis,5分钟有效期"""
        key = f"sms_code:{phone}"
        self.redis.setex(key, expire, code)
    
    def check_code(self, phone, code):
        """校验验证码"""
        key = f"sms_code:{phone}"
        stored_code = self.redis.get(key)
        return stored_code and stored_code.decode() == code
  1. 视图层处理逻辑
# views.py
from django.http import JsonResponse
from utils.sms import SMSUtil, generate_code
import requests

def send_sms_code(request):
    if request.method != 'POST':
        return JsonResponse({'status': 'error', 'msg': '请求方法错误'})
    
    phone = request.POST.get('phone')
    if not phone or len(phone) != 11:
        return JsonResponse({'status': 'error', 'msg': '手机号格式错误'})
    
    # 生成6位验证码
    code = generate_code(6)
    
    # 调用云片API发送短信
    params = {
        'apikey': settings.YP_API_KEY,
        'mobile': phone,
        'text': f'您的验证码是{code}。如非本人操作,请忽略本短信',
    }
    
    try:
        resp = requests.post('https://sms.yunpian.com/v2/sms/single_send.json', data=params)
        result = resp.json()
        
        if result.get('code') == 0:
            # 发送成功,保存到Redis
            sms_util = SMSUtil()
            sms_util.save_code(phone, code)
            return JsonResponse({'status': 'success'})
        else:
            return JsonResponse({'status': 'error', 'msg': result.get('msg')})
    except Exception as e:
        return JsonResponse({'status': 'error', 'msg': str(e)})

四、前端交互实现

  1. HTML模板部分
<!-- templates/register.html -->
<div class="form-group">
    <label for="phone">手机号</label>
    <div class="input-group">
        <input type="text" id="phone" name="phone" class="form-control">
        <span class="input-group-btn">
            <button id="getCodeBtn" class="btn btn-default" type="button">获取验证码</button>
        </span>
    </div>
</div>
<div class="form-group">
    <label for="code">验证码</label>
    <input type="text" id="code" name="code" class="form-control">
</div>
  1. JavaScript交互逻辑
// static/js/register.js
$(function() {
    let countdown = 60;
    let timer = null;
    
    $('#getCodeBtn').click(function() {
        const phone = $('#phone').val();
        if (!/^1[3-9]\d{9}$/.test(phone)) {
            alert('请输入正确的手机号');
            return;
        }
        
        // 禁用按钮,防止重复点击
        $(this).attr('disabled', true);
        
        $.ajax({
            url: '/send_sms_code/',
            type: 'POST',
            data: {phone: phone},
            success: function(res) {
                if (res.status === 'success') {
                    // 开始倒计时
                    timer = setInterval(function() {
                        countdown--;
                        $('#getCodeBtn').text(`${countdown}秒后重新获取`);
                        
                        if (countdown <= 0) {
                            clearInterval(timer);
                            $('#getCodeBtn').text('获取验证码').attr('disabled', false);
                            countdown = 60;
                        }
                    }, 1000);
                } else {
                    alert(res.msg);
                    $('#getCodeBtn').attr('disabled', false);
                }
            },
            error: function() {
                alert('网络错误,请重试');
                $('#getCodeBtn').attr('disabled', false);
            }
        });
    });
});

五、安全优化措施

  1. 频率限制



    • 同一手机号60秒内只能发送一次
    • 每天最多发送10次验证码
  2. 防刷策略



    • IP限流
    • 图形验证码二次验证(针对频繁请求)
  3. 验证码失效机制



    • 设置5分钟有效期
    • 验证成功后立即删除

六、常见问题解决方案

  1. 短信延迟问题



    • 前端显示"验证码已发送,可能稍有延迟"
    • 设置120秒的有效期缓冲
  2. 多设备登录冲突



    • 每次新验证码生成会覆盖旧验证码
    • 记录最后一次发送的验证码
  3. 国际化支持



    • 根据用户区域选择短信模板
    • 支持多语言验证码提示

通过以上完整实现,我们的Django商城项目已经具备了一套稳定可靠的短信验证码系统。在实际项目中,还可以考虑加入Celery异步任务队列来进一步提升用户体验,避免网络延迟导致的界面卡顿。

用户点击获取验证码按钮前端发送AJAX请求到后端后端生成随机验证码并存入Redis调用短信平台API发送验证码用户提交表单时验证码校验
朗读
赞(0)
版权属于:

至尊技术网

本文链接:

https://www.zzwws.cn/archives/41111/(转载时请注明本文出处及文章链接)

评论 (0)

人生倒计时

今日已经过去小时
这周已经过去
本月已经过去
今年已经过去个月

最新回复

  1. 强强强
    2025-04-07
  2. jesse
    2025-01-16
  3. sowxkkxwwk
    2024-11-20
  4. zpzscldkea
    2024-11-20
  5. bruvoaaiju
    2024-11-14

标签云