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

news2024/11/20 18:24:39

全栈开发一条龙——前端篇
第一篇:框架确定、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中查看

添加成功~

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LangChain带你轻松玩转ChatGPT等大模型开发

大家好&#xff0c;我是herosunly。985院校硕士毕业&#xff0c;现担任算法研究员一职&#xff0c;热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名&#xff0c;CCF比赛第二名&#xff0c;科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的…

CDN管理平台安装说明

CDN管理平台安装说明 系统需求 操作系统&#xff1a;Linux CPU不少于1核心 可用内存不少于1G 可用硬盘空间不小于10G 对于每日千万访问以上的CDN系统推荐配置如下&#xff1a; CPU不少于8核心 可用内存不少于8G 可用硬盘空间不小于200G 准备工作 在安装GoEdge之前&#xff0…

集中电表抄表系统

1.集中电表抄表系统的简述 集中电表抄表系统是一种现代化电力管理方法&#xff0c;它通过自动化的形式搜集、解决与分析电力耗费数据信息&#xff0c;大大提升了电力行业经营效率。这类系统的主要目标是替代传统的人工抄水表方法&#xff0c;降低不正确&#xff0c;提升数据的…

【linux】详解vim编辑器

基本指令 【linux】详解linux基本指令-CSDN博客 【linux】详解linux基本指令-CSDN博客 vim的基本概念 vim有很多模式&#xff0c;小编只介绍三种就能让大家玩转vim了&#xff0c; 分别是&#xff1a; 正常/普通/命令模式 插入模式 末行/底行模式 命令模式 控制屏幕光标的…

Java面试八股之进程和线程的区别

Java进程和线程的区别 定义与作用&#xff1a; 进程&#xff1a;在操作系统中&#xff0c;进程是程序执行的一个实例&#xff0c;是资源分配的最小单位。每个进程都拥有独立的内存空间&#xff0c;包括代码段、数据段、堆空间和栈空间&#xff0c;以及操作系统分配的其他资源…

IT革命浪潮:技术革新如何改变我们的生活与工作

一、技术革新与行业应用 当前的IT行业正处于前所未有的技术革新阶段。其中&#xff0c;量子计算和虚拟现实是两项引人注目的技术。 量子计算&#xff1a;量子计算以其超越传统计算的潜力&#xff0c;正在逐步从理论走向实践。在材料科学、药物研发和气候模型等复杂计算领域&a…

前端学习-day08

文章目录 01-相对定位02-绝对定位03-绝对定位居中04-固定定位05-堆叠顺序06-CSS精灵-基本使用07-案例-京东服务08-字体图标10.垂直对齐方式11-过度12-透明度13-光标类型14-轮播图 01-相对定位 <!DOCTYPE html> <html lang"en"> <head><meta ch…

计算机网络学习小结_数据链路层

数据链路和帧 帧&#xff1a;数据链路层传输基本单元。链路层将网络层传过来的数据构成帧发到链路上&#xff0c;并将发到链路层的帧取出数据交给网络层 数据报/分组/包&#xff1a;网络层传输基本单元 三个基本问题 即封装成帧、透明传输、差错检测 封装成帧 概念&#…

阿木实验室联合openEuler开源社区-Embedded SlG组(海思项目)参加第五届「开源之夏」,参赛学生火热招募中...

开源之夏是中国科学院软件研究所发起的“开源软件供应链点亮计划”系列暑期活动&#xff0c;旨在鼓励高校学生积极参与开源软件的开发维护&#xff0c;促进优秀开源软件社区的蓬勃发展。活动联合各大开源社区&#xff0c;针对重要开源软件的开发与维护提供项目开发任务&#xf…

java+ vue.js+uniapp一款基于云计算技术的企业级生产管理系统,云MES源码 MES系统如何与ERP系统集成?

java vue.jsuniapp一款基于云计算技术的企业级生产管理系统&#xff0c;云MES源码&#xff0c;MES系统如何与ERP系统集成&#xff1f; MES系统&#xff08;制造执行系统&#xff09;与ERP系统&#xff08;企业资源规划系统&#xff09;的集成可以通过多种方式实现&#xff0c;这…

3D工业视觉

前言 本文主要介绍3D视觉技术、工业领域的应用、市场格局等&#xff0c;主要技术包括激光三角测量、结构光、ToF、立体视觉。 一、核心内容 3D视觉技术满足工业领域更高精度、更高速度、更柔性化的需求&#xff0c;扩大工业自动化的场景。 2D视觉技术基于物体平面轮廓&#…

LabVIEW超高温高压流变仪测试系统

LabVIEW超高温高压流变仪测试系统 超高温高压流变仪广泛应用于石油、天然气、化工等行业&#xff0c;用于测量材料在极端条件下的流变特性。随着计算机技术、测试技术和电子仪器技术的快速发展&#xff0c;传统的流变仪测试方式已无法满足现代工业的需求。因此&#xff0c;开发…

JavaFX学习教程一

一、准备工作 Jdk 从 1.8 起支持 JavaFx&#xff0c;到 Jdk 11 不再包含 JavaFx&#xff0c;而是改为 OpenJFX&#xff0c;需要另行安装。 以下是JavaFX的官方教程&#xff1a; java8(java1.8)的客户端技术说明指南(开发工具为NetBeans IDE )&#xff1a;客户端技术&#xf…

C++—结构体

结构体&#xff08;struct&#xff09;&#xff0c;是一种用户自定义复合数据类型&#xff0c;可以包含不同类型的不同成员。 结构体的声明定义和使用的基本语法&#xff1a; // 声明结构体struct 结构体类型 { 成员1类型 成员1名称; ...成员N类型 成员N名称; };除声明…

rockylinux 利用nexus 搭建私服yum仓库

简单说下为啥弄这个私服&#xff0c;因为自己要学习一些东西&#xff0c;比如新版的k8s等&#xff0c;其中会涉及到一些yum的安装&#xff0c;为了防止因网络问题导致yum安装失败&#xff0c;和重复下载&#xff0c;所以弄个私服&#xff0c;当然也有为了意外保障的想法&#x…

网络安全技术与应用:远程控制与数据库安全

实验准备 软件&#xff1a;VMware Workstation Pro 虚拟机&#xff1a;Red Hat Enterprise Linux 7 服务器&#xff0c;Red Hat Enterprise Linux 7 客户端 网络模式&#xff1a;NAT模式 1、配置服务器及客户端网络 服务器IP 客户端IP 测试相互通信 在客户机上设置镜像&#…

nssctf——web

[SWPUCTF 2021 新生赛]gift_F12 1.打开环境后&#xff0c;这里说要900多天会有flag&#xff0c;这是不可能的 2.f12查看源码&#xff0c;然后在html中查找flag &#xff08;在最上方的栏目中&#xff0c;或者按ctrlf&#xff09; [SWPUCTF 2021 新生赛]jicao 1.打开环境是一段…

【MySQL】MySQL的安装和基本概念

MySQL的安装和基本概念 一、环境安装1、环境及配置2、下载安装 二、基本概念1、主流数据库2、mysql和mysqld的区别和概念&#xff08;1&#xff09;概念1&#xff1a;了解CS结构&#xff08;2&#xff09;概念2&#xff1a;数据库指的是什么&#xff08;3&#xff09;概念3&…

模板中的右值引用(万能引用)、引用折叠与完美转发

模板中的右值引用&#xff08;万能引用&#xff09;、引用折叠与完美转发 文章目录 模板中的右值引用&#xff08;万能引用&#xff09;、引用折叠与完美转发一、万能引用与引用折叠1. 模板中的右值引用2. 自动类型推导(auto)与万能引用3. 引用折叠与万能引用4. lambda表达式捕…

巨某量引擎后台登录实战笔记 | Playwright自动化框架

前言 本文章中所有内容仅供学习交流&#xff0c;抓包内容、敏感网址、数据接口均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff0c;若有侵权&#xff0c;请联系我立即删除&#xff01; 入正题看看滑块是怎么个事…