全栈实现发送验证码注册账号 全栈开发之路——全栈篇(3)

全栈开发一条龙——前端篇
第一篇:框架确定、ide设置与项目创建
第二篇:介绍项目文件意义、组件结构与导入以及setup的引入。
第三篇:setup语法,设置响应式数据。
第四篇:数据绑定、计算属性和watch监视
第五篇 : 组件间通信及知识补充
第六篇:生命周期和自定义hooks
第七篇:路由
第八篇:传参
第九篇:插槽,常用api和全局api。
全栈开发一条龙——全栈篇
第一篇:初识Flask&MySQL实现前后端通信
第二篇: sql操作、发送http请求和邮件发送

上次我们实现了发邮件,这次我们来实现一个场景:发送随机验证码,限时5分钟,通过才能注册账号。本文将一步步展开实现这个小功能。
先配置好redis库:参考资料使用zip安装方式更加方便快捷。

文章目录

  • 后端
    • 一、生成随机验证码
    • 二、保存验证码
    • 三、验证邮箱&蓝图创建
    • 四、功能整合
  • 前端
    • 入口文件
    • 实现组件
    • 开放局域网端口
  • 验证码验证和数据库操作

后端

一、生成随机验证码

要实现随机验证码,我们先引入python自带的random

def random_code(pure_num = True):
    if pure_num == True:
        rand_temp = random.randint(100000,999999)
        rand_str = str(rand_temp)
    else:
        base_str = "0123456789qwertyuiopasdfghjklzxcvbnm"
        rand_str=""
        for _ in range(6):
            rand_str += random.choice(base_str)
    return rand_str

我们首先加入一个判断,需要的随机序列是否需要是纯数字,如果是我们就生成一个6位数,然后转化为str。如果不是纯数字,我们先写一个选择序列,就是所有数字和字母的字符串,然后用随机函数抽取,添加到我们的结果字符串中,最后返回。
注意不要忘记给rand_str赋初值,不然不能用rand_str += xxx.

有很多人喜欢写列表推导式
、
性能确实不错,但如果你是我同事,我也略懂一些拳脚。

二、保存验证码

我们首先进入data文件,配置以下redis数据库对象

import redis
rd = redis.Redis(decode_responses=True)

然后我们去业务文件mail_send.py中进行缓存操作。

from data import rd

先导入redis对象
然后用原子操作设定数据对应关系和缓存时间

def save_random_code(email,code,lifelong=300):
    error_ju = rd.setex(email,lifelong,code)
    #返回是否保存成功
    return error_ju

第二行代码 参数分别是 key 周期 value
周期就是数据存在的时间,单位是s,此处就是数据存在5分钟。

save_random_code(email="scls@qq.com", code=random_code() , lifelong=50)

测试一下,打开redis的cli界面,发现是存储成功的

过了我设置的50秒lifelong之后再次查询

发现缓存消失了。

redis-cli的语句有如下几句,各位可以自行测试:
ttl key 看剩下的生命周期
get key 查看数据
keys * 查看有哪些key

三、验证邮箱&蓝图创建

接下来,我们准备进入发送验证邮件的步骤了,我们首先要验证邮箱的合法性

import re
def is_valid_email(email):
    ex_email = re.compile(r'^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$')
    #匹配正则
    res = ex_email.match(email)
    return bool(res)

这里正则看不懂没关系,正常业务中都是直接上网查的。此处就是保证一下邮箱的基本格式,然后我们在发邮件,用验证码的方式判断邮箱是否是真实的。

我们为这个发邮件功能专门写一个蓝图(为了方便管理,事实上就是解耦合、对象封装的思想)

from flask import Blueprint,jsonify,request
from flask.views import MethodView
from data import db,rd

from mail_send import is_valid_email
user_view = Blueprint("user_view",__name__)

class code_sending_verify(MethodView):
    def get(self):
        email = request.args.get("email",None)
        if not email:
            return jsonify( {"errcode":1,"msg":"缺失邮箱"} )
        if not is_valid_email(email=email):
            return jsonify( {"errcode":2,"msg":"邮箱不合法"} )
        return jsonify( {"errcode":0,"msg":"发送成功"} )
   
#配置类视图
user_view.add_url_rule("/sendcode/",view_func=code_sending_verify.as_view("code_sending_verify")  )

然后再manage中注册蓝图

from user_verify import user_view
app.register_blueprint(user_view)

这样我们就为/sendcode/路由加上功能了。
然后我们用test尝试是否有bug

res = httpapi.test_get("http://localhost:5000/sendcode/",data={"email":"123123@163.com"})    
res = res.encode('utf-8').decode('unicode_escape')
print(res)

四、功能整合

最后,我们将功能整合,通过get方式访问这个路径就可以完成以下逻辑:
如果传入了一个有效邮箱,那就发送验证码并保存,不然就抛出那一步遇到问题。

from flask import Blueprint,jsonify,request
from flask.views import MethodView
from data import db,rd

from mail_send import is_valid_email,send_email,random_code,save_random_code


user_view = Blueprint("user_view",__name__)

class code_sending_verify(MethodView):
    def get(self):
        # 传入邮箱
        email = request.args.get("email",None)
        if not email:
            return jsonify( {"errcode":1,"msg":"缺失邮箱"} )
        if not is_valid_email(email=email):
            return jsonify( {"errcode":2,"msg":"邮箱不合法"} )
        mail = send_email()
        verify_code = random_code()

        mail.send_mail(dest_mail=email,title="验证码",content=verify_code)
        correctly_save = save_random_code(email=email,code=verify_code,lifelong=180)
        
        if not correctly_save:
            return jsonify( {"errcode":3,"msg":"保存失败"} )
        

        return jsonify( {"errcode":0,"msg":"发送成功"} )
    

#配置类视图
user_view.add_url_rule("/sendcode/",view_func=code_sending_verify.as_view("code_sending_verify")  )

前端

入口文件

下载阿里的组件库,这用就不用你亲自写样式,非常方便
npm install antd

注:如果以下内容有提示报错,请去env.d.ts中加入declare module '*.vue’就好了

import testapi from '@/components/API1.vue'

先把app(前端入口文件写好)

<template>
  <testapi/>   
</template>


<script setup name="app">

import testapi from '@/components/API1.vue'

</script>

<style>
</style>

然后我们主要写组件。

实现组件

style中是样式,可以网上直接找的,不再多说。
说说思路,我们现在上方添加一个输入框,用于输入邮箱,然后将这个数据绑定给email。
然后我们写一个按钮,这个按钮绑定一个方法,点击之后,将email传给我们刚刚发邮箱的后端代码。
然后接收返回值,打印到控制台上方便调试
我们的axios是用来方便我们发送方http请求的,是第三方库,使用很便捷,输入npm i axios就可以安装了。

alert方法是window.alert方法的简写,可以用来唤出提示框

window还有许多很好用的方法和属性,这里附上中文说明window详细说明

完整代码如下:

<template>

<div>
<!-- <input type="text" name="text" placeholder="请输入你的注册id" class="input" v-model="user_id"> -->
<input type="text" name="text" placeholder="请输入你的注册邮箱" class="input" v-model="email">
<!-- <input type="text" name="text" placeholder="请输入你的用户名" class="input" v-model="name">
<input type="text" name="text" placeholder="请输入你的密码" class="input" v-model="pwd"> -->


<button @click="send_mail">
  <div class="svg-wrapper-1">
    <div class="svg-wrapper">
      <svg
        xmlns="http://www.w3.org/2000/svg"
        viewBox="0 0 24 24"
        width="115"
        height="24"
      >
        <path fill="none" d="M0 0h24v24H0z"></path>
        <path
          fill="currentColor"
          d="M1.946 9.315c-.522-.174-.527-.455.01-.634l19.087-6.362c.529-.176.832.12.684.638l-5.454 19.086c-.15.529-.455.547-.679.045L12 14l6-8-8 6-8.054-2.685z"
        ></path>
      </svg>
    </div>
  </div>
  <span>Send</span>
</button>


</div>

<!-- 
<div>
      <h3>{{ user_id }}</h3>
      <h3>{{ email }}</h3>
      <h3>{{ name }}</h3>
      <h3>{{ pwd }}</h3>

</div> -->
</template>


<script setup name="testapi">
    import { ref } from 'vue';
    import axios from 'axios';
    let user_id =ref("")
    let email =ref("")
    let name =ref("")
    let pwd =ref("")
    

    async function send_mail(){
       try{
      let result=await axios.get('http://127.0.0.1:5000/sendcode/',{params:{email:email.value}})
      if(result.data.errorcode != 0)
            {window.alert(result.data.msg)}
       console.log(result.data)
         } catch(error){alert(error)}
           
    }



</script>


<style>
/* id */
.input[type = "text"] {
  display: block;
  color: rgb(34, 34, 34);
  background: linear-gradient(142.99deg, rgba(217, 217, 217, 0.63) 15.53%, rgba(243, 243, 243, 0.63) 88.19%);
  box-shadow: 0px 12px 24px -1px rgba(0, 0, 0,0.18);
  border-color: rgba(7, 4, 14, 0);
  border-radius: 50px;
  block-size: 20px;
  margin: 7px auto;
  padding: 18px 15px;
  outline: none;
  text-align: center;
  width: 200px;
  transition: 0.5s;
}
.input[type = "text"]:hover {
  width: 240px;
}
.input[type = "text"]:focus {
  width: 280px;
}
/* id */

/* button_send */
button {
  font-family: inherit;
  font-size: 20px;
  background: royalblue;
  color: white;
  padding: 0.7em 1em;
  padding-left: 0.9em;
  display: flex;
  align-items: center;
  border: none;
  border-radius: 16px;
  overflow: hidden;
  transition: all 0.2s;
  cursor: pointer;
}

button span {
  display: block;
  margin-left: 0.3em;
  transition: all 0.3s ease-in-out;
}

button svg {
  display: block;
  transform-origin: center center;
  transition: transform 0.3s ease-in-out;
}

button:hover .svg-wrapper {
  animation: fly-1 0.6s ease-in-out infinite alternate;
}

button:hover svg {
  transform: translateX(1.2em) rotate(45deg) scale(1.1);
}

button:hover span {
  transform: translateX(5em);
}

button:active {
  transform: scale(0.95);
}

@keyframes fly-1 {
  from {
    transform: translateY(0.1em);
  }

  to {
    transform: translateY(-0.1em);
  }
}

/* button_send */
</style>

开放局域网端口

我们用 npm run dev -- --host 0.0.0.0 --port 5173来启动我们的前端服务,然后把我们刚刚写好的访问后端的网址改成后端的服务端口

可以在我们启动后端服务的地方看到


之后我们的前端服务会跳出来我们可以访问的局域网网址,在手机上也可以访问哦~

验证码验证和数据库操作

我们先在api中再加入一个按钮,绑定一个方法


    async function verify_code(){
       try{
       let result=await axios.get('http://127.0.0.1:5000/verify_code/',{params:{    
            email:email.value,
            code:verify_code_txt.value,
            id:user_id.value,
            password:pwd.value,
            name : name.value}})

        window.alert(result.data.msg)
         } catch(error){
           alert(error)

        }         
    }

跟之前一样,讲数据传递给后端进行验证

class verify_code(MethodView):
    #验证验证码
    def get(self):

        email=request.args.get("email",None)
        id=request.args.get("id",None)
        name=request.args.get("name",None)
        password=request.args.get("password",None)
        verify_code = request.args.get("code",None)
        print(email,id,name,password,verify_code,"\n\n\n\n")



        saved_code = rd.get(email)
        
        if not saved_code:
            return jsonify( {"errcode":5,"msg":"未向该邮箱发送验证码或超时"} )
        
        if saved_code != verify_code:
            return jsonify( {"errcode":6,"msg":"验证码错误"} )
        
        res = test_post("http://localhost:5000/insert/",data={"id":id,"name":name,"email":email,"password":password})

        return jsonify( {"errcode":0,"msg":"注册成功"} )
        
user_view.add_url_rule("/verify_code/",view_func=verify_code.as_view("verify_code")  )        

我们先判断,如果验证码是一样的,拿我们就调用之前写好的加入数据库的接口。
进入mysql中查看

添加成功~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/635749.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

分布式音乐播放器适配了Stage模型

OpenAtom OpenHarmony&#xff08;以下简称“OpenHarmony”&#xff09;应用开发自API 8及其更早版本一直使用的是FA模型进行开发。FA模型是Feature Ability的缩写&#xff0c;它和PA&#xff08;Particle Ability&#xff09;两种类型是过往长期推广的术语&#xff0c;深入人心…

6.2 else if语句

本节必须掌握的知识点&#xff1a; 示例代码二十 代码分析 汇编解析 ■if语句表达形式3 if(表达式1) statement1 else if(表达式2) statement2 else if(表达式3) statement3 …… else statementN 解析&#xff1a; 如果表达式1非0&#xff0c;则执行statement1&#…

Java基础22(JSON解析 注解)

目录 一、JSON解析 1. JSON语法 2. JSON的用途 3. Java解析JSON 4. 使用Fastjson 4.1 Fastjson 的优点 4.2 Fastjson 导包 4.3 Fastjson的主要对象 4.4 常用方法 将Java对象 "序列化"&#xff08;转换&#xff09; 为JSON字符串&#xff1a; 将JSON字符串…

go语言中的一个特别的语法 //go:embed 可将将静态文件内容读取到string, []byte和 embed.FS 变量并直接打包到exe包中

go语言中的一个特别的语法 //go:embed 看上去像是注释&#xff0c;实则是golang中的一个内置的语法&#xff0c;而且是仅在你的go代码编译时生效的语法&#xff0c; 借助他我们可以将我们的静态资源文件读取到FS直接打包到我们的exe执行文件中。 同时他还支持文件的模式匹配…

C#中BufferedStream类详解与示例

文章目录 1. BufferedStream的基本介绍2. 创建BufferedStream对象从现有Stream创建指定缓冲区大小 3. 使用BufferedStream读取数据写入数据 4. BufferedStream的注意事项5. 示例代码 在C#中&#xff0c;BufferedStream是一个非常有用的流类&#xff0c;它提供了缓冲功能&#x…

出谈论点云文件pcd加载01

刚写完基于potree开发地图水印效果的时候&#xff0c;在网上分享实例&#xff0c;刚发出去&#xff0c;竟然被人喷了&#xff0c;这么简单的实例&#xff0c;竟然好意思发群里&#xff0c;哎… 好无奈&#xff01; 不过我还是坚持我的想法&#xff0c;大家看到文章后&#xff0…

JVM严镇涛版笔记【B站面试题】

前言 2023-06-19 18:49:33 出自B站 灰灰的Java面试 枫叶云链接&#xff1a;http://cloud.fynote.com/s/4976 JVM面试题大全 Lecturer &#xff1a;严镇涛 1.为什么需要JVM&#xff0c;不要JVM可以吗&#xff1f; 1.JVM可以帮助我们屏蔽底层的操作系统 一次编译&#xff0c…

Windows安全应急--应急排查的一些方法

前言&#xff1a; 非法BC植入网站安全应急&#xff0c; 在安全应急中&#xff0c; 总会需要大大小小的问题&#xff0c; 就像成长一样。 检测工具尽量使用轻量级的。。 本次演示环境 Windows Server 2008 问题排查步骤&#xff1a; 先判断服务器有没有被Rootkit 查看登录…

[STM32-HAL库]Flash库-HAL库-复杂数据读写-STM32CUBEMX开发-HAL库开发系列-主控STM32F103C6T6

目录 一、前言 二、实现步骤 1.STM32CUBEMX配置 2.导入Flash库 3.分析地址范围 4.找到可用的地址 5.写入读取普通数据 6.写入读取字符串 6.1 存储相关信息 6.2 存取多个参数 三、总结及源码 一、前言 在面对需要持久化存储的数据时&#xff0c;除了挂载TF卡&#xff0c;我们…

java技术:oauth2协议

目录 一、黑马程序员Java进阶教程快速入门Spring Security OAuth2.0认证授权详解 1、oauth服务 WebSecurityConfig TokenConfig AuthorizationServer 改写密码校验逻辑实现类 2、oauth2支持的四种方式&#xff1a; 3、oauth2授权 ResouceServerConfig TokenConfig 4、…

CSS学习笔记之高级教程(二)

10、CSS 3D 转换 通过 CSS transform 属性&#xff0c;您可以使用以下 3D 转换方法&#xff1a; rotateX()rotateY()rotateZ() 10.1 rotateX() 方法&#xff08;使元素绕其 X 轴旋转给定角度&#xff09; <!DOCTYPE html> <html lang"en"><head&g…

2024-05-23 vscode + clang + clangd 解锁 modules

点击 <C 语言编程核心突破> 快速C语言入门 vscode clang clangd 解锁 modules 前言一、准备二、使用备注: 总结 前言 要解决问题: 昨天解锁VS使用modules, 但是不完美, 没有代码提示和补全了, 今天用 vscode clang clangd 解锁 modules, 同时还有代码补全及提示. …

第十一章 文件及IO操作

第十一章 文件及IO操作 文件的概述及基本操作步骤 文件&#xff1a; 存储在计算机的存储设备中的一组数据序列就是文件不同类型的文件通过后缀名进行区分 文本文件&#xff1a;由于编码格式的不同&#xff0c;所占磁盘空间的字节数不同(例如GBK编码格式中一个中文字符占2字…

K8S集群再搭建

前述&#xff1a;总体是非常简单的&#xff0c;就是过程繁琐&#xff0c;不过都是些重复的操作 master成员: [controller-manager, scheduler, api-server, etcd, proxy,kubelet] node成员: [kubelet, proxy] master要修改的配置文件有 1. vi /etc/etcd/etcd.conf # 数…

【设计模式深度剖析】【4】【创建型】【建造者模式】| 类比选购汽车的过程,加深理解

&#x1f448;️上一篇:抽象工厂模式 | 下一篇:原型模式&#x1f449;️ 目录 建造者模式概览定义英文原话直译如何理解呢&#xff1f;建造者模式将对象的建造过程给抽象出来了类比选购汽车 4个角色UML类图1. 抽象建造者&#xff08;Builder&#xff09;角色2. 具体建造者…

盲人社会适应性训练:打开生活的新篇章

在现代社会的快节奏中&#xff0c;每一位成员都在寻求更好的方式来适应环境&#xff0c;对于盲人群体而言&#xff0c;这种适应性尤为关键。盲人社会适应性训练作为一个旨在提升盲人生活质量和独立性的系统性过程&#xff0c;正逐步受到广泛关注。在这一过程中&#xff0c;一款…

安灯呼叫系统解决方案在生产中的应用

工厂安灯呼叫系统是一种用于监控工厂设备运行情况和生产状况的系统。它通常包括各种传感器和监控设备&#xff0c;可以实时监测工厂的生产流程&#xff0c;提供运行状态、故障警报、生产效率等信息。通过工厂安灯系统&#xff0c;工厂管理人员可以及时了解生产情况&#xff0c;…

探数API统计分享-中国各省人均消费支出

根据2017年至2021年的统计数据&#xff0c;我国各省&#xff08;市、区&#xff09;的人均消费支出情况各不相同。其中&#xff0c;上海的人均消费支出最高&#xff0c;达到了2021年的48879元&#xff0c;位居全国之首。紧随其后的是北京&#xff0c;人均消费支出为43640元。 相…

肯尼亚大坝决堤反思:强化大坝安全监测的必要性

一、背景介绍 近日&#xff0c;肯尼亚发生了一起严重的大坝决堤事件。当地时间4月29日&#xff0c;肯尼亚内罗毕以北的一座大坝决堤&#xff0c;冲毁房屋和车辆。当地官员称&#xff0c;事故遇难人数已升至71人。这起事件再次提醒我们&#xff0c;大坝安全无小事&#xff0c;监…

【机器学习高级】强化学习综述

文章目录 一、说明二、强化学习是什么&#xff1f;2.1 与现代神经网络的相异2.2 强化学习属于行为学派2.3 强化学习数学支持 三、强化学习有什么好处&#xff1f;3.1 在复杂环境中表现出色3.2 需要较少的人际互动3.3 针对长期目标进行优化 四、强化学习有哪些用例&#xff1f;4…