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 = 'xxx@qq.com' # 填邮箱
MAIL_PASSWORD = 'xxxx' # 填授权码
FLASK_MAIL_SENDER = '皮皮虾!我们走!<xxxx@qq.com>' #邮件发送方
FLASK_MAIL_SUBJECT_PREFIX = '[皮皮虾!我们走]' #邮件标题
#MAIL_DEFAULT_SENDER = 'xxx@qq.com' # 填邮箱,默认发送者**加粗样式**
发送邮箱是基于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='验证码发送成功')
发送邮件
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 = '''
<h1>
亲爱的,
</h1>
<h3>
欢迎来到 <b>Flask-Test-Project</b>!
</h3>
<p>
您的验证码为 <b>{mailcode}</b> 赶快去完善注册信息吧!!!
</p>
<p>感谢您的支持和理解</p>
<p>来自:Flask-Test-Project</p>
<p><small>{time}</small></p>
'''.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="修改密码成功")