使用Flask-Mail和实现邮箱激活账户

使用Flask-Mail和实现邮箱激活账户 - 图1

写在前面

  1. 首先现在很多网站注册都要求你使用邮箱验证或者绑定邮箱,这里使用Flask-Mail帮助我们快速实现发邮件。我折腾了一段时间,然后才搞好。记录一下,防止以后忘记了。
  2. 很久没有更新博客的原因就是在忙着做小学期的项目,然后刚好用上了Flask-Mail,就正好记录一下。

使用Flask-Mail

首先是安装:

  1. pip install flask-mail

然后在Flask中,我们激活一个扩展:

  1. from flask_mail import Mail
  2. mail = Mail()
  3. mail.init_app(app)

然后是关于Flask-Mail的配置:

  1. MAIL_SERVER="smtp.qq.com"
  2. MAIL_PORT=465
  3. MAIL_USE_SSL=True
  4. MAIL_USERNAME="发送邮件的邮箱"
  5. MAIL_PASSWORD="xxxxxxxxxxxxxxx"
  6. MAIL_DEFAULT_SENDER=('Yznx 岳钊钊', MAIL_USERNAME)

对参数进行解释:

  • 第一个是你使用哪个邮箱服务商来发提供服务,常见的网上很容易就搜到
  • 发送邮件的端口,和邮箱服务商对应起来
  • 是否开启ssl加密
  • 发送邮件的邮箱
  • 授权码(邮箱密码),QQ邮箱会生成授权码
  • 邮件默认的发送者

然后就是发送邮件的相关方法了:

  1. def _send_async_mail(app, message):
  2. with app.app_context():
  3. mail.send(message)
  4. def send_message(to, subject, template, **kwargs):
  5. message = Message(subject, recipients=[to])
  6. message.html = render_template(template + '.html', **kwargs)
  7. app = current_app._get_current_object()
  8. thr = Thread(target=_send_async_mail, args=[app, message])
  9. thr.start()
  10. return thr
  11. def send_confirm_email(user, token, to=None):
  12. send_message(subject='Email Confirm', to=to or user.email, template='email/activate', user=user, token=token)

第一个方法是发送邮件,将邮件发送出去,但是send()方法需要上下文,所以我们使用app_context()来发送

第二个方法的作用就是实例化一个message对象和开启一个新的进程来发送邮件

第三个方法作用就是调用发送

实现邮箱验证功能

这个问题还是折磨了我一段时间,然后我在网上查找信息最后总结,终于完成了这个功能。

获取token

  1. 我在模型中定义了一个方法来产生token
  1. from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
  2. def generate_confirmation_token(self, expiration=3600):
  3. s = Serializer(current_app.config['SECRET_KEY'], expiration)
  4. return s.dumps({'confirm': self.id})

关于Python中获取token和验证token是通过itsdangerous这个库来实现的。首先是引入的方法,一定要引入正确的。然后呢配置过期时间为3600,单位为秒。他在生成对象的时候会调用配置中的秘钥,所以秘钥也是很重要的,需要配置好的。我们将用户的ID进行编码和序列化然后返回。

  1. 验证token
  1. def confirm(self, token):
  2. s = Serializer(current_app.config['SECRET_KEY'])
  3. try:
  4. data = s.loads(token) # 解码
  5. except Exception as e:
  6. return False
  7. if data.get('confirm') != self.id:
  8. return False
  9. self.status = True
  10. db.session.commit()
  11. return True

通过解码进行对比,如果是就修改状态码。

视图函数

视图函数如下:

  1. @user_bp.route("/send_activate/<int:user_id>")
  2. def send_activate(user_id):
  3. user = User.query.filter(User.id == user_id).first()
  4. if user.status:
  5. return redirect(".home")
  6. token = user.generate_confirmation_token()
  7. send_confirm_email(user=user, token=token)
  8. flash(u'激活邮件已发送,请注意查收邮箱')
  9. return render_template("user/activate.html")
  10. @user_bp.route("/activation/<token>")
  11. def activation(token):
  12. if current_user.confirm(token):
  13. flash(u'账户已成功激活!')
  14. return redirect(url_for(".home"))
  15. else:
  16. flash(u'激活失败,请重试')
  17. return render_template("user/activate.html") # 到激活界面

一个是发送验证邮箱的,在函数中获取token,发送邮件。一个是验证token。大概就是这样,弄明白了还是很简单。

我做好了,可以看一下效果:

使用Flask-Mail和实现邮箱激活账户 - 图2

然后点击就会跳入到你的Home页面。