Flask 发送邮件实现——附Flask发送邮件验证码实现

Flask 邮件操作

发送邮件

注册获取邮件系统授权码

Flask 发送邮件实现——附Flask发送邮件验证码实现_第1张图片
按着提示获取到授权码
Flask 发送邮件实现——附Flask发送邮件验证码实现_第2张图片

目录结构

Flask 发送邮件实现——附Flask发送邮件验证码实现_第3张图片


### 配置配置文件
# 邮箱配置
MAIL_SERVER = "smtp.qq.com"
MAIL_USE_TLS = True
MAIL_PORT = 587
# 你个人的邮箱
MAIL_USERNAME = "[email protected]"

# 刚刚获取到的授权码填在这里
MAIL_PASSWORD = "xxxxxx"
# 你的邮箱名字可以和MAIL_USERNAME一样
MAIL_DEFAULT_SENDER = "[email protected]"

发送邮件


很简单,导入flask_mail 库,只需要2行代码就可以发送邮件。

pip install flask-mail

from flask_mail import Message


@bp.route("/mail/test")
def mail_test():
	# recipients是接收人,是一个数组可以给多人同时发送邮件
    message = Message(subject="菜鸡学安全1111", recipients=['[email protected]'], body="这是一条测试邮件!!!")
    mail.send(message)
    return "邮件发送成功"

Flask 发送邮件实现——附Flask发送邮件验证码实现_第4张图片

进阶——发送邮件验证码并存储到数据库中

后端代码代码

我这里使用蓝图,把其他接口放在auth.py中

auth.py

import random
from flask import Blueprint, render_template, jsonify
from exts import mail, db
from flask_mail import Message
from flask import request
import string
from models import EmailCaptchaModel

# /auth
bp = Blueprint("auth", __name__, url_prefix="/auth")


# 也就是前面已经定义好前缀,/auth/login
@bp.route("/login")
def login():
    pass


@bp.route("/register")
def register():

    # 验证用户提交的邮箱和验证码是否对应且正确
    return render_template("register.html")


# bp.route: 如果没有指定methods参数,默认就是GET请求
@bp.route("/captcha/email")
def get_email_captcha():
    # url传参数
    # /captcha/[email protected]
    email = request.args.get("email")
    print(email)
    # 6位,数字和字母的组成
    source = string.digits*6
    captcha = random.sample(source, 6)
    # 列表变成字符串
    captcha = "".join(captcha) # 965083
    print(captcha)

    # I/O 操作
    message = Message(subject="菜鸡学安全", recipients=[email], body=f"您的验证码是:{captcha}")
    mail.send(message)


    # 使用数据库存储
    email_captcha = EmailCaptchaModel(email=email, captcha=captcha)
    db.session.add(email_captcha)
    db.session.commit()

    # RESTful API,这是一个格式
    # {code:200/400/500, message: "xxx", data: {}}


    return jsonify({"code":200, "message": "", "data": None})

    # memcached 和redis 适合存储验证,这里扩展,这里暂用数据库来存储



@bp.route("/mail/test")
def mail_test():
    # message = Message(subject="菜鸡学安全1111", recipients=['[email protected]'], body="你好我是开发,你好,面试邀请,请你及时确认。")
    # mail.send(message)
    return "邮件发送成功"

数据库配置
class EmailCaptchaModel(db.Model):
    __tablename__ = "eamil_captcha"
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    email = db.Column(db.String(100), nullable=False)
    captcha = db.Column(db.String(100), nullable=False)

app.py
from flask import Flask
import config
from exts import db, mail
from models import UserModel
from blueprints.qa import bp as qa_bp
from blueprints.auth import bp as auth_bp
from flask_migrate import Migrate
from models import EmailCaptchaModel


app = Flask(__name__)
app.config.from_object(config)


# 创建app后,再与db 和app绑定
db.init_app(app)

# 初始化mail连接
mail.init_app(app)


migrate = Migrate(app, db)

# blueprint,用来做模块化的
# 蓝图,视图函数模块化,蓝图


# 注册蓝图
app.register_blueprint(qa_bp)
app.register_blueprint(auth_bp)

@app.route('/')
def hello_world():  # put application's code here
    return 'Hello World!'


if __name__ == '__main__':
    app.run()

前端代码

register.js

// 绑定按钮操作,整个网页都加载完毕后才会在执行的

function bindEmailcaptchaClick(){
    $("#captcha-btn").click(function (event){
        //$this 就是点前按钮jequery对象
        var $this = $(this);

        // 阻止默认动作
        event.preventDefault();

        var email=  $("input[name='email']").val();
        $.ajax({

            url: "/auth/captcha/email?email="+email,
            method: "GET",
            success: function (result){
                var code = result['code'];
                if(code == 200){
                    var countdown = 60;

                    //开始倒计时之前,就取消点击事件
                    $this.off("click");
                    var timer = setInterval(function (){
                        $this.text(countdown)
                        countdown -=1
                        if(countdown <=0){
                            //清掉定时器,就不倒计时了
                            clearInterval(timer)
                            $this.text("获取验证码");
                            bindEmailcaptchaClick();
                            // 重新绑定事件

                        }
                    },1000)

                    alert("邮件发送成功!")
                }else{
                    alert(result['message'])
                }
            },
            fail: function (error){
                console.log(error);
            }
        })
    });
}


$(function(){
    bindEmailcaptchaClick();
})

register.html
{% extends "base.html" %}

{% block title %}菜鸡学安全-注册{% endblock %}

{% block head %}
    <script src="{{ url_for('static', filename='jquery/jquery.3.6.min.js') }}"></script>
    <script src="{{ url_for('static', filename='js/register.js') }}"></script>
{% endblock %}

{% block body %}
<div class="row mt-4">
            <div class="col"></div>
            <div class="col">
                <form method="POST" action="#">
                    <div class="form-group">
                        <label for="exampleInputEmail1">邮箱</label>
                        <input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" name="email">
                        <small id="emailHelp" class="form-text text-muted">我们不会把邮箱用于其他用户</small>
                    </div>
                    <div class="form-group">
                        <label for="exampleInputEmail1">验证码</label>
                        <div class="input-group">
                            <input type="text" class="form-control" name="captcha">
                            <div class="input-group-append">
                                <button class="btn btn-outline-secondary" type="button" id="captcha-btn">获取验证码</button>
                            </div>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="exampleInputEmail1">用户名</label>
                        <input type="text" class="form-control" name="username">
                    </div>
                    <div class="form-group">
                        <label for="exampleInputPassword1">密码</label>
                        <input type="password" class="form-control" id="exampleInputPassword1" name="password">
                    </div>
                    <div class="form-group">
                        <label for="exampleInputPassword1">确认密码</label>
                        <input type="password" class="form-control" name="password_confirm">
                    </div>
                    <button type="submit" class="btn btn-primary btn-block">立即注册</button>
                </form>
            </div>
            <div class="col"></div>
        </div>
{% endblock %}

register.html用到的父模板

base.html

DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="{{ url_for('static',filename='/bootstrap/bootstrap.4.6.min.css') }}">
    <link rel="stylesheet" href="{{ url_for('static',filename='/css/init.css') }}">
    {% block head %}{% endblock %}
    <title>{% block title %}{% endblock %}title>
head>

<body>
    <nav class="navbar navbar-expand-lg navbar-light bg-light">
        <div class="container">
            <a class="navbar-brand" href="#">菜鸡学安全a>
            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon">span>
            button>
            <div class="collapse navbar-collapse" id="navbarSupportedContent">
                <ul class="navbar-nav mr-auto">
                    <li class="nav-item active">
                        <a class="nav-link" href="/">首页 <span class="sr-only">(current)span>a>
                    li>
                    <li class="nav-item">
                        <a class="nav-link" href="#">发布问答a>
                    li>
                    <li class="nav-item ml-2">
                        <form class="form-inline my-2 my-lg-0" method="GET" action="#">
                            <input class="form-control mr-sm-2" type="search" placeholder="关键字" aria-label="Search" name="q">
                            <button class="btn btn-outline-success my-2 my-sm-0" type="submit">搜索button>
                        form>
                    li>
                ul>
                <ul class="navbar-nav">
                    <li class="nav-item">
                        <a class="nav-link" href="#">登录a>
                    li>
                    <li class="nav-item">
                        <a class="nav-link" href="#">注册a>
                    li>
                ul>
            div>
        div>
    nav>
    <div class="container">
        {% block body %}{% endblock %}
    div>
body>

html>

实例图

Flask 发送邮件实现——附Flask发送邮件验证码实现_第5张图片
Flask 发送邮件实现——附Flask发送邮件验证码实现_第6张图片


数据库
Flask 发送邮件实现——附Flask发送邮件验证码实现_第7张图片

参考文章

https://www.bilibili.com/video/BV17r4y1y7jJ

你可能感兴趣的:(开发,flask,python,后端)