• 8.python发送邮箱验证码——使用zmail发送邮件验证用户信息


    1.邮件工具类封装

    1.1概述

    在我们的注册页面时,会需要一个发送邮件的功能去验证邮箱号是否正确,同样的,可以避免一些用户恶意的注册导致数据库出现问题在这里插入图片描述
    这里将使用zmail的第三方库去实现发送邮件的功能:zmail官方网址

    1.2实现功能流程

    1. 安装zmail
    pip install zmail
    
    • 1
    1. 去到邮箱中开启服务IMAP/SMTP服务 (什么是 IMAP,它又是如何设置?)
      在这里插入图片描述
    2. 获取到授权码进行填写到代码中

    1.3封装代码实现

    # forum/utils/email_utils.py
    import zmail
    # 'qzjwvrycoxovhgfh'
    def send_mail(from_mail:str, passwd:str, to_mail:str, subject:str, text:str) -> None:
        server = zmail.server(from_mail,passwd)
        server.send_mail(to_mail,{'subject':subject,'content_text':text})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.邮件接口开发

    在这里插入图片描述

    2.1概述

    当我们点击发送验证码时,需要一个接口去调用我们的封装好的邮件工具类去实现此功能。

    2.2Tornado创建控制器

    # forum/handler/UserHandler.py
    from forum.wtforms import UserForm
    from forum import manager
    from forum.models import UserModel
    from uuid import uuid4
    from forum.handler.BaseHandler import BaseHandler
    from forum.utils.email_utils import send_mail
    from random import randint
    from config import email
    
    # 发送邮件
    class SendEmailHandler(BaseHandler):
        # 用于给定4位随机验证码
        def generate_code(self) -> int:
            return randint(1000,9999)
        # 发送邮件的接口
        def post(self):
            user_email = self.get_body_argument('email') # 获取前端form输入框中输入的邮箱
            msg = f'您好,您正在使用{user_email}注册用户注册账号,您的验证码位{self.generate_code()},如果不是本人操作,请忽略'
            send_mail(email.get('uname'),email.get('pwd'),user_email,'用户注册',msg)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    2.3挂载路由

    # router.py
    from forum.handler import BaseHandler,UserHandler
    handlers = [
        ('/',BaseHandler.IndexHandler),
        ('/api/user/add/?', UserHandler.AddUserHandler),
        ('/api/send_msg/?', UserHandler.SendEmailHandler)
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.4发送地址参数文件

    # config.py
    
    email = {
        'uname':'1339559006@qq.com',
        'pwd':'qzjwvrycoxovhgfh'
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3.效果展示

    在这里插入图片描述

    4.发送验证码_验证码保存

    4.1概述

    当我们想要注册时,必须先发送验证码(下一步再进行验证),发送完成,我们应该把数据保存到数据库中,但是这里的数据并不是特别重要,所以会放在缓存类型的数据库redis,最后在进行验证码的比对。这里,我们就实现如何将数据保存到redis中。

    4.2连接数据库redis

    在这里插入图片描述

    4.3安装redis第三方库

    网址如下:官方网址

    pip install redis
    
    • 1

    4.4连接虚拟机中的redis数据库

    在虚拟机开启服务后,连接数据库redis,具体的redis配置方法太多了,就不在这一一介绍啦
    在这里插入图片描述

    4.5测试数据库连接代码

    # 测试:redis数据库是否可使用
    def test_redis_db():
        import redis
        # 连接数据库
        client = redis.Redis(host='192.168.188.128',port=6379,db=0)
        # 添加数据
        client.set('name','bjsxt')
        print(client.get('name'))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    4.6 保存数据到redis,从redis获取数据

    # forum/utils/redis_utils.py
    
    import redis
    
    # 保存数据到redis
    def save_code(email:str, code:str)->None:
        client = redis.Redis(host='192.168.188.128', port=6379,db=0)
        client.set(email, code)
    
    # 从redis获取数据
    def get_code(email:str) ->str:
        client = redis.Redis(host='192.168.188.128',port=6379,db=0)
        code = client.get(email)
        if code:
            return code.decode()
        else:
            return ''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    4.7验证数据代码完整版

    # forum/handler/UserHandler.py
    from forum.wtforms import UserForm
    from forum import manager
    from forum.models import UserModel
    from uuid import uuid4
    from forum.handler.BaseHandler import BaseHandler
    from forum.utils.email_utils import send_mail
    from forum.utils.redis_utils import *
    from random import randint
    from config import email
    
    
    # 调用wtforms做添加用户数据之前的数据表单验证
    class AddUserHandler(BaseHandler):
        async def post(self):
            # 创建应该响应对象
            rs_data = {}
            # 接受请求的参数并封装到Form对象中
            user_form = UserForm(self.request.arguments)
            # 前端传递的验证码
            code = self.get_body_argument('code')
            # 后端的正确的验证码
            db_code = get_code(user_form.email.data)
            if code == db_code:
                if user_form.validate():
                    # 从表单中获取email信息
                    email = user_form.email.data
                    try:
                        # 异步查询数据表信息
                        exist_user = await manager.get(UserModel,email = email)
                        if exist_user:
                            # 存在此用户,验证失败
                            rs_data['code'] = 500
                            rs_data['msg'] = '用户名已存在'
                    except Exception as e:
                        # 验证成功
                        # 异步保存数据到数据库中
                        user_form.id.data = uuid4()
                        await manager.create(UserModel,**user_form.data)
                        rs_data['code'] = 200
                        rs_data['msg'] = '注册成功'
                else:
                    # 验证失败
                    rs_data['code'] = 500
                    rs_data['msg'] = '注册失败'
                    # 将验证失败的具体原因返回给rs_data,提示信息
                    for f in user_form.errors:
                        rs_data[f] = user_form.errors[f][0]
            else:
                # 验证失败
                    rs_data['code'] = 500
                    rs_data['msg'] = '验证码错误'
            self.finish(rs_data)
    
        
    # 发送邮件
    class SendEmailHandler(BaseHandler):
        # 用于给定4位随机验证码
        def generate_code(self) -> int:
            return randint(1000,9999)
        # 发送邮件的接口
        def post(self):
            user_email = self.get_body_argument('email') # 获取前端form输入框中输入的邮箱
            code = self.generate_code()
            msg = f'您好,您正在使用{user_email}注册用户注册账号,您的验证码位{code},如果不是本人操作,请忽略'
            send_mail(email.get('uname'),email.get('pwd'),user_email,'用户注册',msg)
            save_code(user_email,code)
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    4.8效果展示

    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    Redis数据持久化(持久化过程中写操作如何处理)
    【JavaEE 学习笔记】JavaScript(WebAPI)附代码案例,猜数字网页版(完整版源码)
    电脑重装系统 win11 怎么关闭系统软件通知
    [Linux入门]---文本编辑器vim使用
    39 对称二叉树
    尚医通gateway配置bug
    深度学习之卷积神经网络(CNN)
    MySQL索引
    Springboot启动流程分析(四):完成启动流程
    flume笔记(三):自定义-自定义interceptor/自定义source/自定义sink
  • 原文地址:https://blog.csdn.net/m0_63953077/article/details/127751709