天天看点

Django网站开发中如何利用邮箱发送邮件实现验证功能1、配置邮件服务器2、使用 django.core.mail.send_mail() 发送邮件3、邮件的验证功能实现

文章目录

  • 1、配置邮件服务器
  • 2、使用 django.core.mail.send_mail() 发送邮件
  • 3、邮件的验证功能实现

1、配置邮件服务器

在学习怎么写代码来发送邮箱之前,我们先来认识下Django发送邮箱的过程是怎么样的。

Django网站开发中如何利用邮箱发送邮件实现验证功能1、配置邮件服务器2、使用 django.core.mail.send_mail() 发送邮件3、邮件的验证功能实现

如上图,我们的客户端是将邮件发送到一个叫做 SMTP 的服务器上面,SMTP转发邮件到 POP3 上,最后我们的用户从 POP3 去取邮件,这样的一个过程。

所以,我们在写具体的实现代码之前,需要配置好第三方的邮箱服务器。配置好了才可以借助第三方的服务器完成发送邮箱的功能。

Django网站开发中如何利用邮箱发送邮件实现验证功能1、配置邮件服务器2、使用 django.core.mail.send_mail() 发送邮件3、邮件的验证功能实现

配置完成后,我们只需要负责做好我们的客户端如何和SMTP之间通讯即可。我们Django的商城客户端通过send_mall()方法来发送邮箱到SMTP。如上图,我们需要传入这些参数即可。

接下来,我们来配置邮箱服务器。这里已QQ邮箱为例子。

I、点击进入"设置",进入"帐户",下拉找到"POP3"

Django网站开发中如何利用邮箱发送邮件实现验证功能1、配置邮件服务器2、使用 django.core.mail.send_mail() 发送邮件3、邮件的验证功能实现
Django网站开发中如何利用邮箱发送邮件实现验证功能1、配置邮件服务器2、使用 django.core.mail.send_mail() 发送邮件3、邮件的验证功能实现

点击"开启",开启POP3/SMTP服务,发送 短信验证

Django网站开发中如何利用邮箱发送邮件实现验证功能1、配置邮件服务器2、使用 django.core.mail.send_mail() 发送邮件3、邮件的验证功能实现

保存授权码,在你的项目中会用到

Django网站开发中如何利用邮箱发送邮件实现验证功能1、配置邮件服务器2、使用 django.core.mail.send_mail() 发送邮件3、邮件的验证功能实现

最后,在你项目的settings.py中添加以下代码

# EMAIL 发邮件服务器的配置
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'  # 指定邮件后端
EMAIL_HOST = 'smtp.qq.com'  # 发邮件主机
EMAIL_PORT = 25  # 发邮件端口
EMAIL_HOST_USER = '159****[email protected]'  # 授权的邮箱
EMAIL_HOST_PASSWORD = 'fsie****dwfgbj'  # 邮箱授权时设置或者获取的授权码,非注册登录密码
EMAIL_FROM = '大象商城<159****[email protected]>'  # 发件人抬头
           

2、使用 django.core.mail.send_mail() 发送邮件

配置完成第三方的邮箱服务器之后,接下来,我们只需调用send_mail()方法,来给SMTP发送邮件就可以了。这里只需把send_mail需要的参数准备好传入就可以了。

Django网站开发中如何利用邮箱发送邮件实现验证功能1、配置邮件服务器2、使用 django.core.mail.send_mail() 发送邮件3、邮件的验证功能实现

定义一个签名工具类,加密userid

# sign.py

from django.conf import settings
from itsdangerous import TimedJSONWebSignatureSerializer, BadSignature


class Signer(object):

    def __init__(self, expires_in):
        self.serializer = TimedJSONWebSignatureSerializer(settings.SECRET_KEY, expires_in)

    def sign(self, obj):
        """
        对python字典先进行json序列化,再对序列化结果进行签名
        :param obj:
        :return: 签名后的字符串
        """
        token = self.serializer.dumps(obj)
        return token.decode()

    def unsign(self, s):
        """
        对传入的字符串验证签名, 验证成功返回字符串中的被签名的数据对应的python字典
        :param s: 要验证的签名字符串
        :return: python字典
        """
        try:
            obj = self.serializer.loads(s)
        except BadSignature:
            obj = None
        return obj
           

具体的实现代码:

# views.py

userid = {"user_id": request.user.id}
token = Signer(constants.EMAIL_VERIFY_SIGN_EXPIRES).sign(userid)
verify_url = settings.EMAIL_VERIFY_URL + "?token=" + token
subject = "大象商城邮箱验证"
message = ""
from_email = settings.EMAIL_FROM
recipient_list = [email]
html_message = '<p>尊敬的用户您好!</p>' \
               '<p>感谢您使用蜗牛商城。</p>' \
               '<p>您的邮箱为:%s 。请点击此链接激活您的邮箱:</p>' \
               '<p><a href="%s" target="_blank" rel="external nofollow" >%s<a></p>' % (email, verify_url, verify_url)
send_mail(subject, message, from_email, recipient_list, html_message=html_message)
           

这里我们实现的同步的发送邮箱验证的功能,但是发送邮件验证是耗时的操作,会阻塞我们的商城的响应,所以可以用异步发送邮件。使用celery实现异步任务。

Django网站开发中如何利用邮箱发送邮件实现验证功能1、配置邮件服务器2、使用 django.core.mail.send_mail() 发送邮件3、邮件的验证功能实现

3、邮件的验证功能实现

当点击邮件中的链接之后,就会触发验证的功能。

# urls.py
re_path(r"^emails/verification/$", views.EmailVerifyView.as_view(), name="emails_verify"),
           
# views.py
class EmailVerifyView(View):
    def get(self, request):
        """
        激活邮箱
        :param request:
        :return:
        """
        # 1.服务器提取签名后的 userid
        token = request.GET.get('token')
        # 2.对userid进行签名验证, 验证失败,返回错误信息
        if not token:
            return HttpResponseForbidden("缺少必须参数")
        user_id: dict = Signer(constants.EMAIL_VERIFY_SIGN_EXPIRES).unsign(token)
        if not user_id or 'user_id' not in user_id.keys():
            return HttpResponseForbidden("token 无效")
        try:
            # 3.1 查询userid是否存在, userid不存在,返回错误信息
            user = User.objects.get(id=user_id.get("user_id"))
            # 3.2 修改用户表中邮箱为激活状态
            user.email_active = True
            user.save()
        except User.DoesNotExist:
            return HttpResponseForbidden("激活邮箱失败")
        # 4.重定向到用户中心页面
        return redirect(reverse("users:info"))