前端弹窗的验证码验证操作

部署运行你感兴趣的模型镜像

一、HTML代码

<div id="myModal" class="modal" onsubmit="return captchaSubmit();">
                    <form action="/verify" method="post"><input type="hidden" id="deviceZz" name="deviceZz" value="value">
                      <div class="modal-content">
                        <span class="modal-close">&times;</span>
                        <p>
                          <label for="operator">操作人:</label>
                          <input type="text" id="operator" name="operator">
                        </p>
                        <p>
                          <label for="password">密码:</label>
                          <input type="password" id="password" name="password">
                        </p>
                        <p>
                            <img id="captcha" src="/captcha" alt=""/>
                            <br >
                          <input type="text" id="captchaInput" placeholder="请输入验证码" name="captchainput">
                            <button onclick="refreshCaptcha()">刷新</button>
                        </p>
                        <div class="button-group">
                            <button id="submitModal">提交</button>
                            <button id="cancelModal">取消</button>
                        </div>
                      </div>
                    </form>
                </div>

验证码部分的代码

                         <p>
                            <img id="captcha" src="/captcha" alt=""/>
                            <br >
                          <input type="text" id="captchaInput" placeholder="请输入验证码" name="captchainput">
                            <button onclick="refreshCaptcha()">刷新</button>
                        </p>

1.captchaSubmit()包含了在点击提交后,前后端发生交互的一系列操作。包括简单的前端对于操作人密码验证码非空的判断,然后将这些字段打包发给后端,后端进行验证,对数据库中的字段进行匹配,返回json结果,前端收到后判断是否提交表单的一些流程。

2."/verify"用于前端向后端发送数据的,后端验证数据并返回结果

3."/captcha"用于前端需要刷新验证码时,使用get方法从后端获取的验证码图片的src

4.refreshCaptcha()用于刷新验证码,获取src

二、前端js代码

// 模态框中的确定按钮点击事件,写一些因为用户查询未规范填写字段或身份密码验证码输入错误的拦截表单提交的操作
submitModal.onclick=function captchaSubmit() {

    var operator = document.getElementById('operator').value;
    var password = document.getElementById('password').value;
    var captchaInput = document.getElementById('captchaInput').value;

    // 检查是否所有输入框都有值
    if (!operator || !password || !captchaInput) {
        alert('请填写所有字段');
        return false; // 阻止表单提交
    }

    // 创建一个FormData对象来发送数据
    var formData = new FormData();
    formData.append('operator', operator);
    formData.append('password', password);
    formData.append('captchainput', captchaInput);

    // 使用fetch发送数据到服务器
    fetch('/verify', {
        method: 'POST',
        body: formData
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            //数据成功验证,弹窗自动关闭,方便用户继续进行页面其他操作
            modal.style.display = "none";
            alert('提交成功');
             // 刷新页面
            window.location.reload(true);
            return true;
        } else {
            if (data.error === 'operator') {
                // 提交失败,清空输入框
                document.getElementById('operator').value = '';
                document.getElementById('password').value = '';
                document.getElementById('captchaInput').value = '';
                refreshCaptcha(); // 刷新验证码
                alert('身份不存在,请重新输入');
            }
                else if(data.error === 'password') {
                    document.getElementById('password').value = '';
                    document.getElementById('captchaInput').value = '';
                    refreshCaptcha(); // 刷新验证码
                    alert('密码错误,请重新输入');
            } else if (data.error === 'captcha') {
                alert('验证码错误,请重新输入');
                document.getElementById('captchaInput').value = '';
                refreshCaptcha(); // 刷新验证码
            }
        }
    })
    .catch(error => console.error('Error:', error));
    // 阻止表单的默认提交行为
    return false;
}
//刷新验证码
function refreshCaptcha(){
    document.getElementById('captcha').src='/captcha?t='+new Date().getTime();
}

三、后端代码(FLASK)

@yzm_bp.route('/captcha', methods=['get'])
def captcha():
    try:
        # 生成验证码
        code, image = generate_code()
        session['captcha'] = code  # 存储验证码到session
        # 将图像保存到字节流中
        image_stream = BytesIO()
        image.save(image_stream, 'PNG')
        image_stream.seek(0)
        # 返回图像给用户
        return send_file(image_stream, mimetype='image/png')
    except Exception as e:
        print("生成错误")
# 验证用户输入
@yzm_bp.route('/verify', methods=['POST'])
def verify():
    operator = request.form['operator']
    password = request.form['password']
    captcha_input = request.form['captchainput']

    try:
        connection = pymysql.connect(**db_config)
        try:
            with connection.cursor() as cursor:
                sql_list = "select password from operate where operator=%s"
                cursor.execute(sql_list, operator)
                results = cursor.fetchone()
        finally:
            connection.close()
    except pymysql.MySQLError as e:
        print(f"error connecting to mysql:{e}")

    # 验证密码
    if results is None:
        return jsonify({'success': False, 'error': 'operator'})
    else:
        if password!=results[0]:
            return jsonify({'success': False, 'error': 'password'})
        else:
            # 验证验证码
            session_captcha = session.get('captcha')  # 从session中获取验证码
            if captcha_input.lower() != session_captcha.lower():
                return jsonify({'success': False, 'error': 'captcha'})
            else:
                return jsonify({'success': True, 'error': ''})
             

四、验证码生成(python)

import os
import random
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont


def random_str():
    '''
    获取一个随机字符, 数字或小写字母
    :return:
    '''
    random_num = str(random.randint(1, 9))
    random_low_alpha = chr(random.randint(97, 122))
    while random_low_alpha in ['i', 'o', 'l']:  # 移除i o l不易识别验证码
        random_low_alpha = chr(random.randint(97, 122))
    random_char = random.choice([random_num, random_low_alpha])
    return random_char


def random_color():
    '''
    验证码字体颜色
    '''
    c1 = random.randint(0, 255)
    c2 = random.randint(0, 255)
    c3 = random.randint(0, 255)
    return c1, c2, c3


def generate_picture(width=120, height=35):
    '''
    生成验证码图片
    '''
    image = Image.new('RGB', (width, height), random_color())
    return image


def draw_str(count, image, font_size):
    '''
    在图片上写随机字符
    :param count: 字符数量
    :param image: 图片对象
    :param font_size: 字体大小
    :return:
    '''
    draw = ImageDraw.Draw(image)
    # 获取一个font字体对象参数是ttf的字体文件的目录,以及字体的大小
    font_file = os.path.join('arial.ttf')
    font = ImageFont.truetype(font_file, size=font_size)
    temp = []
    for i in range(count):
        random_char = random_str()
        draw.text((10 + i * 30, -2), random_char, random_color(), font=font)
        temp.append(random_char)

    valid_str = ''.join(temp)  # 验证码
    return valid_str, image


def noise(image, width=120, height=35, line_count=3, point_count=20):
    '''
    生成图片干扰信息
    :param image: 图片对象
    :param width: 图片宽度
    :param height: 图片高度
    :param line_count: 线条数量
    :param point_count: 点的数量
    :return:
    '''
    draw = ImageDraw.Draw(image)
    for i in range(line_count):
        x1 = random.randint(0, width)
        x2 = random.randint(0, width)
        y1 = random.randint(0, height)
        y2 = random.randint(0, height)
        draw.line((x1, y1, x2, y2), fill=random_color())

        # 画点
        for i in range(point_count):
            draw.point([random.randint(0, width), random.randint(0, height)], fill=random_color())
            x = random.randint(0, width)
            y = random.randint(0, height)
            draw.arc((x, y, x + 4, y + 4), 0, 90, fill=random_color())

    return image


def generate_code():
    '''
    生成验证码
    :return:str code
    '''
    image = generate_picture()
    valid_str, image = draw_str(4, image, 35)
    image = noise(image)

    return valid_str, image

五、结论

我是针对用户对上一个表单的操作进行用户权限的验证写的代码,如果有其他的场景,部分代码可灵活运用。

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值