很多Web应用需要在诸如用户注册、密码找回等过程中,进行用户身份的有效性认证。采用电子邮箱进行确认是一种常用的方式。Python标准库smtplib可以实现发送电子邮件的功能,Flask框架的Flask-mail包装了smtplib库,扩展了对电子邮件发送的支持。
0x01 安装Flask-mail
可以采用pip安装Flask-mail:
pip install flask-mail1
0x02 初始化配置
创建email的蓝本(app/__init__.py
):
from app.email import email as blueprint_email
app.register_blueprint(blueprint_email,url_prefix='/email')12
在初始化文件中导入mail对象:
from flask_mail import Mail
mail=Mail(app)
Flask-mail可以连接SMTP服务器,并把邮件利用这个服务器发送出去。Flask-mail需要进行参数配置,常见参数如下:
序号 |
参数 |
默认值 |
说明 |
1 |
MAIL_SERVER |
localhost |
SMTP服务器主机或者IP地址 |
2 |
MAIL_PORT |
25 |
电子邮件服务器端口 |
3 |
MAIL_USE_TLS |
False |
是否启用传输层安全协议(TLS) |
4 |
MAIL_USE_SSL |
False |
是否启用安全套接层协议(SSL) |
5 |
MAIL_USERNAME |
None |
电子邮箱账号用户名 |
6 |
MAIL_PASSWORD |
None |
电子邮箱账号密码 |
7 |
MAIL_DEBUG |
False |
是否启动调试 |
在config.py
配置文件中设置(以126邮箱为例,需要开启SMTP服务):
#邮件配置MAIL_SERVER='smtp.126.com'MAIL_PORT=25MAIL_USE_TLS=TrueMAIL_USERNAME='***@126.com'MAIL_PASSWORD='******'MAIL_DEBUG=True1234567
0x03 发送邮件
完成初始化后,创建一个Message实例,包含需要发送邮件的信息(文件/app/email/views.py
)。
#coding:utf-8from flask import render_template,current_appfrom app.email import emailfrom flask_mail import [email protected]('/send/<string:content>',methods=['POST','GET'])def sendmail(content):
#发送邮件
msg=Message(u'邮件主题',sender='***@126.com',recipients=['***@qq.com'])
msg.body=u'邮件内容'
msg.html=u'<h3>邮件html:{0}</h3>'.format(content) #获取当前app对象
app=current_app._get_current_object() with app.app_context(): from app import mail
mail.send(msg) return 'Send'123456789101112131415161718
其中,sender是邮件的发送者,recipients包含了全部收件者的邮箱地址列表。
0x04 改进发送过程
我们可以发现,在发送邮件的过程中,会出现程序停滞现象,浏览器也会出现等待,为了避免这个问题,可以采用异步方式来发送邮件。封装邮件发送函数,并启动子线程来发送邮件(文件/app/email/sendMail.py
):
#coding:utf-8
from flask_mail import Message
from flask import render_template,current_app
from threading import Thread
#发送邮箱的子线程类
class SendMailThread(Thread):
def __init__(self,app,msg):
super(SendMailThread,self).__init__()
self.__app=app
self.__msg=msg #异步发送邮件
def send_asyc_mail(self,app,msg):
with app.app_context():
from app import mail
mail.send(msg)
def run(self):
#发送邮件
self.send_asyc_mail(self.__app,self.__msg)#封装邮件发送过程'''
# 参数:
# subject:邮件主题
# recv:收件邮箱地址
# template:邮件内容的模板
# kw:模板参数键值对列表
'''def send_mail(subject,recv,template,**kw):
msg=Message(subject,sender='***@126.com',recipients=recv)
msg.body=u'邮件内容'
msg.html=render_template(template,**kw) #获取当前app对象
app=current_app._get_current_object() #子线程发送
send=SendMailThread(app,msg)
send.start()12345678910111213141516171819202122232425262728293031323334353637383940
在/app/email/views.py
中定义新的处理函数:
import sendMail
#异步发送邮件
@email.route('/asyc_send/',methods=['POST','GET'])
def sendAsycMail():
subject=u'异步发送邮件测试'
rec=['***@qq.com']
tp='email/send.html'
test='test'
#异步发送邮件
sendMail.send_mail(subject=subject,recv=rec,template=tp,test=test)
return 'Asyc Send!!!'
上面将邮件内容放在模板中,这样更具有扩展性。采用异步方式发送邮件,可以提高用户体检,发送过程也流畅了许多。