发送邮件来让用户激活,因此,邮件中需要包含用户信息。但用户信息需要加密才可以。因此加密采用的是itsdangerous中的TimedJSONWebSignatureSerializer。
参考链接:https://juejin.im/entry/56b30250df0eea0054375e1d
用法和JSON WEB 签名中的用法一样。
加密:
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer # 创建对象, 第一个参数加密密钥,可以随便写,但解密也需要相同的, # 过期事件,秒为单位 serializer = Serializer(settings.SECRET_KEY, 3600) # 要加密的数据 info = {'confirm':zengsf} # 进行加密,token为加密结果,bytes数据 token = serializer.dumps(info) # 转换为utf8格式 token = token.decode()
解密:
# 创建一个对象 serializer = Serializer(settings.SECRET_KEY, 3600) # 将str装换为byte token.encode() # 参数是加密之后的结果,返回是解密之后的结果 info = serializer.loads(token) # 获取值 result = info['confirm']
如果过期的话,会有一个SignatureExpired的签名过期异常。
我们利用邮箱大部分都是163,qq, 126这些邮箱,这些都是免费的,都是smtp模式。
到django中settings.py中进行配置:
# 发送邮箱配置 EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' # smtp服务地址 EMAIL_HOST = 'smtp.163.com' # 端口号 EMAIL_PORT = 25 # 发送邮件的邮箱 EMAIL_HOST_USER = 'zengsf***@163.com' # 在邮箱中设置的客户端授权密码 EMAIL_HOST_PASSWORD = 'zengsf***' # 收件人看到的发件人 EMAIL_FROM = '<zengsf***@163.com>'
然后回到视图中,具体用法:https://yiyibooks.cn/xx/django_182/topics/email.html
from django.core.mail import send_mail
msg='<a href="http://www.127.0.0.1:8000/subject/pythonzly/index.shtml" target="_blank">点击激活</a>' send_mail('注册激活','',settings.EMAIL_FROM, ['zengsf***@163.com'], html_message=msg)
这样就实现了在django中发送邮件消息。但有一个问题就是,send_mail是一个阻塞函数,因此给客户带来长时间等待,体验感不好。然后可以使用celery来解决这个问题。主要就是分三种,发送者,中间人,处理者。
发送者:就是要处理的事件。
中间人:SQLAlchemy、Django ORM、Memcached、 Redis、RPC (RabbitMQ/AMQP)都可以当中间人。
处理者:就是监听中间人,并处理事件。
这里使用redis当中间人。
发送者:-----------------------------------------------
创建一个tasks.py
from celery import Celery from django.conf import settings from django.core.mail import send_mail # 创建一个Celery类的实例对象 app = Celery('demo',broker='redis://:127.0.0.1:6379/1') # 创建任务函数 @app.task def my_task(): msg='<a href="http://www.127.0.0.1:8000/subject/pythonzly/index.shtml" target="_blank">点击激活</a>' send_mail('注册激活','',settings.EMAIL_FROM,['zengsf***@163.com'],html_message=msg)
接着来到发邮件的views中。
from celery_tasks.tasks import my_task # 发送任务, 就会把任务发送到redis中的任务队列中 my_task.delay()
到这里,发送者和中间人就ok了。
处理者:---------------------------------
如果发送者,中间人,处理者在不同的电脑中,但一定要在同一网段中,要确定互相通信。
启动处理者的前提是你的中间人也要开启。由于环境不再一起,因此,处理者那边也要有一份和发送者这边一样的代码。
启动处理者:celery -A celery_tasks.tasks worker -l info
如果这样直接去发邮件话,还会报错,serder = settings.EMAIL_FROM这个错误,这是因为,tasks.py中需要用到django中的配置文件,但由于这里没有启动django项目,因此就报错了。解决方法就是在启动处理者的时候,初始化django里面的配置文件
然后在tasks.py中添加一些初始化功能:
# 在任务处理者一端加这几句 import os import django os.environ.setdefault("DJANGO_SETTINGS_MODULE", "项目名.settings") django.setup()
这样就可以了。