zl程序教程

您现在的位置是:首页 >  后端

当前栏目

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

Python 用户 信息 验证 发送 邮件 验证码 邮箱
2023-09-27 14:23:04 时间

1.邮件工具类封装

1.1概述

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

1.2实现功能流程

  1. 安装zmail
pip install zmail
  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})

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}注册<CMS论坛项目>用户注册账号,您的验证码位{self.generate_code()},如果不是本人操作,请忽略'
        send_mail(email.get('uname'),email.get('pwd'),user_email,'<CMS论坛项目>用户注册',msg)

2.3挂载路由

# router.py
from forum.handler import BaseHandler,UserHandler
handlers = [
    ('/',BaseHandler.IndexHandler),
    ('/api/user/add/?', UserHandler.AddUserHandler),
    ('/api/send_msg/?', UserHandler.SendEmailHandler)
]

2.4发送地址参数文件

# config.py

email = {
    'uname':'1339559006@qq.com',
    'pwd':'qzjwvrycoxovhgfh'
}

3.效果展示

在这里插入图片描述

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

4.1概述

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

4.2连接数据库redis

在这里插入图片描述

4.3安装redis第三方库

网址如下:官方网址

pip install redis

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'))

在这里插入图片描述

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 ''

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}注册<CMS论坛项目>用户注册账号,您的验证码位{code},如果不是本人操作,请忽略'
        send_mail(email.get('uname'),email.get('pwd'),user_email,'<CMS论坛项目>用户注册',msg)
        save_code(user_email,code)


4.8效果展示

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