使用Flask-Mail和实现邮箱激活账户
写在前面
首先现在很多网站注册都要求你使用邮箱验证或者绑定邮箱,这里使用Flask-Mail帮助我们快速实现发邮件。我折腾了一段时间,然后才搞好。记录一下,防止以后忘记了。
很久没有更新博客的原因就是在忙着做小学期的项目,然后刚好用上了Flask-Mail,就正好记录一下。
使用Flask-Mail
首先是安装:
pip install flask-mail
然后在Flask中,我们激活一个扩展:
from flask_mail import Mail
mail = Mail()
mail.init_app(app)
然后是关于Flask-Mail的配置:
MAIL_SERVER="smtp.qq.com"
MAIL_PORT=465
MAIL_USE_SSL=True
MAIL_USERNAME="发送邮件的邮箱"
MAIL_PASSWORD="xxxxxxxxxxxxxxx"
MAIL_DEFAULT_SENDER=('Yznx 岳钊钊', MAIL_USERNAME)
对参数进行解释:
- 第一个是你使用哪个邮箱服务商来发提供服务,常见的网上很容易就搜到
- 发送邮件的端口,和邮箱服务商对应起来
- 是否开启ssl加密
- 发送邮件的邮箱
- 授权码(邮箱密码),QQ邮箱会生成授权码
- 邮件默认的发送者
然后就是发送邮件的相关方法了:
def _send_async_mail(app, message):
with app.app_context():
mail.send(message)
def send_message(to, subject, template, **kwargs):
message = Message(subject, recipients=[to])
message.html = render_template(template + '.html', **kwargs)
app = current_app._get_current_object()
thr = Thread(target=_send_async_mail, args=[app, message])
thr.start()
return thr
def send_confirm_email(user, token, to=None):
send_message(subject='Email Confirm', to=to or user.email, template='email/activate', user=user, token=token)
第一个方法是发送邮件,将邮件发送出去,但是send()
方法需要上下文,所以我们使用app_context()来发送
第二个方法的作用就是实例化一个message对象和开启一个新的进程来发送邮件
第三个方法作用就是调用发送
实现邮箱验证功能
这个问题还是折磨了我一段时间,然后我在网上查找信息最后总结,终于完成了这个功能。
获取token
我在模型中定义了一个方法来产生token:
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
def generate_confirmation_token(self, expiration=3600):
s = Serializer(current_app.config['SECRET_KEY'], expiration)
return s.dumps({'confirm': self.id})
关于Python中获取token和验证token是通过itsdangerous这个库来实现的。首先是引入的方法,一定要引入正确的。然后呢配置过期时间为3600,单位为秒。他在生成对象的时候会调用配置中的秘钥,所以秘钥也是很重要的,需要配置好的。我们将用户的ID进行编码和序列化然后返回。
验证token:
def confirm(self, token):
s = Serializer(current_app.config['SECRET_KEY'])
try:
data = s.loads(token) # 解码
except Exception as e:
return False
if data.get('confirm') != self.id:
return False
self.status = True
db.session.commit()
return True
通过解码进行对比,如果是就修改状态码。
视图函数
视图函数如下:
@user_bp.route("/send_activate/<int:user_id>")
def send_activate(user_id):
user = User.query.filter(User.id == user_id).first()
if user.status:
return redirect(".home")
token = user.generate_confirmation_token()
send_confirm_email(user=user, token=token)
flash(u'激活邮件已发送,请注意查收邮箱')
return render_template("user/activate.html")
@user_bp.route("/activation/<token>")
def activation(token):
if current_user.confirm(token):
flash(u'账户已成功激活!')
return redirect(url_for(".home"))
else:
flash(u'激活失败,请重试')
return render_template("user/activate.html") # 到激活界面
一个是发送验证邮箱的,在函数中获取token,发送邮件。一个是验证token。大概就是这样,弄明白了还是很简单。
我做好了,可以看一下效果:
然后点击就会跳入到你的Home页面。