flask实现发送邮件

Flask-Mail介绍

对于我们来说是幸运的,现在已经有很多外部插件来处理邮件,虽说不能百分百按照我们的想法去处理,但已经相当接近了。
本来这个是实现用户注册时发送邮件,但是忘记密码这块需要邮箱验证,所以就写邮箱验证了,验证码由后台Python生成并缓存到Redis, come on

config配置

 #	redis配置
 REDIS_HOST = "127.0.0.1"
REDIS_PORT = 6379
# REDIS_pwd = 123456
# password = REDIS_pwd

SESSION_TYPE = "redis"
SESSION_REDIS = redis.StrictRedis(host=REDIS_HOST,port=REDIS_PORT)
SESSION_USE_SIGNER = True
PERMANENT_SESSION_LIFETIME = 84600
 
 #QQ邮箱配置
    MAIL_DEBUG = True             # 开启debug,便于调试看信息
    MAIL_SUPPRESS_SEND = False    # 发送邮件,为True则不发送
    MAIL_SERVER = 'smtp.qq.com'   # 邮箱服务器
    MAIL_PORT = 465               # 端口
    MAIL_USE_SSL = True           # 重要,qq邮箱需要使用SSL
    MAIL_USE_TLS = False          # 不需要使用TLS
    MAIL_USERNAME = '[email protected]'  # 填邮箱
    MAIL_PASSWORD = 'xxxx'      # 填授权码
    FLASK_MAIL_SENDER = '皮皮虾!我们走!'   #邮件发送方
    FLASK_MAIL_SUBJECT_PREFIX = '[皮皮虾!我们走]'     #邮件标题
    #MAIL_DEFAULT_SENDER = '[email protected]'  # 填邮箱,默认发送者**加粗样式**

发送邮箱是基于from flask_mail import Mail 这个模块的
init.py里面的配置

	from config import config_map
    mail = Mail()
    # 根据配置模式的名字获取配置参数的类
    config_class = config_map.get(config_name)
    mail.init_app(app)
    # password = config_class.REDIS_pwd
    # 初始化redis工具
    global redis_store
    redis_store = redis.StrictRedis(host=config_class.REDIS_HOST, port=config_class.REDIS_PORT)

邮箱发送验证码

@api.route('/teacher/send/mail', methods=['POST'])
def teacher_send_mail():
    '''发送邮箱验证码'''
    email = request.json.get('email')
    # if not all([email, nickname]):
    if email is None:
        return jsonify(re_code=RET.PARAMERR, msg='请填写完整的注册信息')

    # 邮箱匹配正则
    # ^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$
    # 手机号匹配正则
    # ^0\d{2,3}\d{7,8}$|^1[358]\d{9}$|^147\d{8}$

    if not re.match(r'^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$', email):
        return jsonify(RET.PARAMERR, msg='请填写正确的邮箱')

    # 生成邮箱验证码
    email_code = '%06d' % random.randint(0, 99999)
    current_app.logger.debug('邮箱验证码为: ' + email_code)
    try:
        redis_store.set('EMAILCODE:' + email, email_code, 1800)  # half-hour = 1800有效期
    except Exception as e:
        current_app.logger.debug(e)
        return jsonify(re_code=RET.DBERR, msg='存储邮箱验证码失败')

    # 发送邮件
    send_mail(
        to=email,
        mailcode=email_code
    )

    return jsonify(re_code=RET.OK, msg='验证码发送成功')

发送邮件

email.py

from threading import Thread
from flask import current_app
from flask_mail import Message
from datetime import datetime

from attendance import mail


def send_async_email(app, msg):
    with app.app_context():   # 确认程序上下文被激活
        mail.send(msg)


def send_mail(to, mailcode):
    '''使用新线程异步发送邮箱
    :param to -> 收件人
    :param nickname -> 收件人注册时所填写的昵称
    :param mailcode -> 生成的邮箱验证码
    :return 执行线程
    '''
    app = current_app._get_current_object()
    msg = Message(app.config['FLASK_MAIL_SUBJECT_PREFIX'] + "您的账号注册验证码",
                  sender=app.config['FLASK_MAIL_SENDER'],
                  recipients=[to])
    # 邮件内容会以文本和html两种格式呈现,而你能看到哪种格式取决于你的邮件客户端。
    msg.body = 'sended by flask-email'
    msg.html = '''
    

亲爱的,

欢迎来到 Flask-Test-Project!

您的验证码为    {mailcode}    赶快去完善注册信息吧!!!

感谢您的支持和理解

来自:Flask-Test-Project

{time}

'''.format(mailcode=mailcode, time=datetime.utcnow) thread = Thread(target=send_async_email, args=[app, msg]) thread.start() return thread

验证邮箱验证码

@api.route('/teacher/mail/verification', methods=['POST'])
def verification():
    email = request.json.get('email')
    mailcode = request.json.get('mailcode')
    password = request.json.get('password')
    try:
        mailcode_server = redis_store.get('EMAILCODE:'+ email).decode()
    except Exception as e:
        current_app.logger.debug(e)
        return jsonify(re_code=RET.DBERR, msg='查询邮箱验证码失败')
    if mailcode_server != mailcode:
        current_app.logger.debug(mailcode_server)
        return jsonify(re_code=RET.PARAMERR, msg='邮箱验证码错误')

    teacher = Teacher.query.filter_by(email=email).first()
    user = Users.query.filter_by(username=teacher.sno).first()
    user.password_hash = password
    db.session.add(user)
    db.session.commit()
    return jsonify(errno=RET.OK, errmsg="修改密码成功")

你可能感兴趣的:(flask)