Django发送邮件及邮件激活

根据前端请求头中传入的JWT token的信息,使用DRF中追加的JWT认证判断是否登录

axios.get(this.host + ‘/user/‘, {
                    // 向后端传递JWT token的方法
                    headers: {
                        ‘Authorization‘: ‘JWT ‘ + this.token
                    },
                    responseType: ‘json‘,
                })

在settins配置文件中添加配置DRF的JWT

# 配置DRF
REST_FRAMEWORK = {
    # 异常处理
    ‘EXCEPTION_HANDLER‘: ‘meiduo_mall.utils.exceptions.exception_handler‘,
    #配置JWT作为验证的后端
    ‘DEFAULT_AUTHENTICATION_CLASSES‘: (
        ‘rest_framework_jwt.authentication.JSONWebTokenAuthentication‘,
        ‘rest_framework.authentication.SessionAuthentication‘,
        ‘rest_framework.authentication.BasicAuthentication‘,
    ),
}

在users/models.py文件中,修改User模型类,增加邮箱是否验证的字段

from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.

class User(AbstractUser):
    """用户模型类"""
    email_active = models.BooleanField(default=False, verbose_name=‘邮箱验证状态‘)  # 默认邮件未激活
    class Meta:
        db_table = ‘tb_users‘
        verbose_name = ‘用户‘
        verbose_name_plural = verbose_name

使用迁移命令,迁移模型类在数据库中以表格形式展示

python manage.py makemigrations

python manage.py migrate

在users/urls.py文件中添加路由

urlpatterns=[
# 获取登录用户的详情信息
url(r‘^user/$‘, views.UserDetailView.as_view()),
]

在users/views.py 中新建视图

from rest_framework.generics import RetrieveAPIViewfrom rest_framework.permissions import IsAuthenticated
from . import serializers

# url(r‘^user/$‘, views.UserDetailView.as_view()),
class UserDetailView(RetrieveAPIView):
    """提供登录用户的详情的"""

    # 指定序列化器
    serializer_class = serializers.UserDetailSerializer

    # IsAuthenticated 采用的是JWT的验证
    # 用户身份验证:是否是登录用户
    permission_classes = [IsAuthenticated]

    def get_object(self):
        """返回当前谁是登录用户
        为什么要重写该方法:是因为我们的路由没有主键
        返回的user是JWT验证系统验证后的登录用户
        """
        return self.request.user

注意:访问视图必须要求用户已通过认证(即登录之后)

在users/serializers.py中创建序列化器

from rest_framework import serializers
from .models import User

class UserDetailSerializer(serializers.ModelSerializer):
    """用户详细信息序列化器"""

    class Meta:
        model = User
        # 只负责输出,并指定输出的字段
        fields = (‘id‘, ‘username‘, ‘mobile‘, ‘email‘, ‘email_active‘)

Django中内置了邮件发送功能,被定义在django.core.mail模块中。发送邮件需要使用SMTP服务器,常用的免费服务器有:163126QQ ,先设置一个邮箱为邮件服务器,可以设置自己的邮箱为邮件服务器,下面以163邮件为例,操作步骤如下:

1)注册163邮箱itcast88,登录后设置。

2)在新页面中点击“客户端授权密码”,勾选“开启”,弹出新窗口填写手机验证码。

3)填写授权码。

4)提示开启成功。

接下来需要在项目的Django配置文件settings中,设置邮箱的配置信息:

# 配置邮件服务器
EMAIL_BACKEND = ‘django.core.mail.backends.smtp.EmailBackend‘ # 导入邮件模块
EMAIL_HOST = ‘smtp.163.com‘ # 发邮件主机
EMAIL_PORT = 25 # 发邮件端口
EMAIL_HOST_USER = ‘itcast11@163.com‘ # 授权的邮箱
EMAIL_HOST_PASSWORD = ‘python808‘# 邮箱授权时获得的密码,非注册登录密码 EMAIL_FROM = ‘python<[email protected]>‘# 发件人抬头

在users/views.py中创建新视图,用于保存用户的邮箱信息,注意需要用户登录通过认证后。

from rest_framework.generics import  UpdateAPIView
from rest_framework.permissions import IsAuthenticated

# url(r‘^email/$‘, views.EmailView.as_view()),
class EmailView(UpdateAPIView):
    """更新邮件"""

    # 验证用户身份信息
    permission_classes = [IsAuthenticated]
    # 指定序列化器
    serializer_class = serializers.EmailSerializer

    def get_object(self):
        return self.request.user

在users/urls.py文件中设置添加邮箱的路由信息:

urlpatterns = [

  url(r‘^email/$‘, views.EmailView.as_view()),

]

在users/serializers.py中新建序列化器,用户验证用户提交的邮箱信息。

from rest_framework import serializers
from celery_tasks.email.tasks import send_verify_email

class EmailSerializer(serializers.ModelSerializer):
    """
    邮箱序列化器
    """
    class Meta:
        model = User
        fields = (‘id‘, ‘email‘)
        extra_kwargs = {
            ‘email‘: {
                ‘required‘: True
            }
        }

    def update(self, instance, validated_data):     # 当前的user模型类调用email字段,将经过验证的email保存到这个字段里面
        instance.email = validated_data[‘email‘]
        instance.save()

        # instance 就表示前面指定的User
        # 在完成保存数据的返回之前,生成邮件激活的连接
        verify_url = instance.generate_verify_email_url()

        # 发送激活邮件
        send_verify_email.delay(instance.email, verify_url)

        return instance

补充发送验证邮件

django.core.mail模块提供了send_mail来发送邮件。

send_mail(subjectmessagefrom_emailrecipient_list,html_message=None)

  • subject 邮件标题
  • message 普通邮件正文, 普通字符串
  • from_email 发件人
  • recipient_list 收件人列表
  • html_message 多媒体邮件正文,可以是html字符串

例如:

msg=‘<a href="http://www.itcast.cn/subject/pythonzly/index.shtml" target="_blank">点击激活</a>‘
send_mail(‘注册激活‘,‘‘,settings.EMAIL_FROM, [‘[email protected]‘], html_message=msg)

在保存邮箱的时候,需要向用户发送验证邮件,我们将发送邮件的工作放到celery中异步执行。

在celerytasks目录中新建email目录和`email/_init.py文件和email/tasks.py`文件

email/tasks.py文件中实现发送邮件的异步任务

from django.core.mail import send_mail
from django.conf import settings
from celery_tasks.main import celery_app

@celery_app.task(name=‘send_verify_email‘)
def send_verify_email(to_email, verify_url):
    """
    发送验证邮箱邮件
    :param to_email: 收件人邮箱
    :param verify_url: 验证链接
    :return: None
    """
    subject = "xxxx邮箱验证"
    html_message = ‘<p>尊敬的用户您好!</p>‘                    ‘<p>感谢您使用xxxx。</p>‘                    ‘<p>您的邮箱为:%s 。请点击此链接激活您的邮箱:</p>‘                    ‘<p><a href="%s">%s<a></p>‘ % (to_email, verify_url, verify_url)
    send_mail(subject, "", settings.EMAIL_FROM, [to_email], html_message=html_message)
注意:

在发送邮件的异步任务中,需要用到django的配置文件,所以我们需要修改celery的启动文件main.py,在其中指明celery可以读取的django配置文件,并且注册添加email的任务

# celery服务器的入口
from celery import Celery
# 为celery使用django配置文件进行设置
import os
if not os.getenv(‘DJANGO_SETTINGS_MODULE‘):
    os.environ[‘DJANGO_SETTINGS_MODULE‘] = ‘meiduo_mall.settings.dev‘

# 创建celery客户端实例
celery_app=Celery(‘meiduo‘)
# 加载celery配置
celery_app.config_from_object(‘celery_tasks.config‘)

# 自动注册异步任务:celery会自动的寻找封装异步任务的包里面的tasks.py文件
# 就是告知celery_app去哪里找异步任务
celery_app.autodiscover_tasks([‘celery_tasks.sms‘,‘celery_tasks.email‘])

启动celery:

pycharm 终端terminal进入到包含celery_tasks的目录中,此项目进入到meiduo_mall,输入命令:celery -A celery_tasks.main worker -l info  出现下图所示红圈中标注的send_verify_email,说明发送邮箱验证异步开启成功(另一个send_sms_code是之前做得发送短信的异步任务)

在users/models.py文件中的User模型类中定义生成验证邮箱链接的方法

邮箱的激活链接是用户点击时会访问的网址,我们让用户点击时进入到success_verify_email.html页面

from itsdangerous import TimedJSONWebSignatureSerializer as TJWSSerializer
from django.conf import settings
from . import constants

def generate_verify_email_url(self):
        """
        生成验证邮箱的url
        """
        serializer = TJWSSerializer(settings.SECRET_KEY, expires_in=constants.VERIFY_EMAIL_TOKEN_EXPIRES)
        data = {‘user_id‘: self.id, ‘email‘: self.email}
        token = serializer.dumps(data).decode()
        verify_url = ‘http://www.meiduo.site:8080/success_verify_email.html?token=‘ + token
        return verify_url

新建users/constants.py文件 添加邮箱验证链接有效期

# 邮箱验证链接有效期:一天
VERIFY_EMAIL_TOKEN_EXPIRES=60*60*24

验证邮箱链接

当用户点击邮箱里的链接时,进入到success_verify_email.html页面。

在该页面中,我们将请求网址中用于验证的token发送给后端接口,由后端接口判断token的有效性,如果token有效,则修改邮箱的验证状态,并将处理结果返回给前端展示给用户。

在users/views.py 中新建视图

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

from users.models import User

# url(r‘^emails/verification/$‘, views.VerifyEmailView.as_view()),
class VerifyEmailView(APIView):
    """验证邮件是否是真实的邮件"""

    def get(self, request):
        # 获取token
        token = request.query_params.get(‘token‘)
        if not token:
            return Response({"message":‘缺少token‘}, status=status.HTTP_400_BAD_REQUEST)

        # 验证token,并返回user
        user = User.check_verify_email_token(token)
        if not user:
            return Response({"message": ‘无效的token‘}, status=status.HTTP_400_BAD_REQUEST)

        # 修改当前user的email_active属性的值为True
        user.email_active = True
        user.save()

        return Response({‘message‘:‘Ok‘})

在users/models.py文件中的User模型类中定义验证token的方法

from itsdangerous import TimedJSONWebSignatureSerializer as TJWSSerializer,BadData

@staticmethod
    def check_verify_email_token(token):
        """验证token并获取user"""
        serializer = TJWSSerializer(settings.SECRET_KEY, expires_in=constants.VERIFY_EMAIL_TOKEN_EXPIRES)
        try:
            data = serializer.loads(token)
        # BadData是loads异常的祖宗
        except BadData:
            return None
        else:
            user_id = data.get(‘user_id‘)
            email = data.get(‘email‘)
            try:
                user = User.objects.get(id=user_id, email=email)
            except User.DoesNotExist:
                return None
            else:
                return user

在users/urls.py文件中配置验证邮箱的路由信息

urlpatterns=[
# 验证邮箱
    url(r‘^emails/verification/$‘, views.VerifyEmailView.as_view()),
]

最后测试一下就ok了

原文地址:https://www.cnblogs.com/cl-python/p/9245761.html

时间: 2024-10-05 23:25:05

Django发送邮件及邮件激活的相关文章

Django 发送邮件

Django 发送邮件 本章节涉及django的发邮件模块send_mail.send_mass_mail.EmailMultiAlternatives from django.core.mail import send_mail from django.core.mail import send_mass_mail from django.core.mail import EmailMultiAlternatives 1. 配置相关参数 如果用的是 163的企业邮箱,settings配置类似于

redis(保存邮件激活码)

官网下载: http://redis.io/download 使用对应位数操作系统文件夹下面命令启动 redis redis-server.exe 服务启动程序 redis-cli.exe 客户端命令行工具 redis.conf 服务配置文件 通过 redis-server.exe 启动服务,默认端口 6379 通过 redis-cli.exe 启动客户端工具 使用Jedis和图形界面工具操作redis 网址: https://github.com/xetorthio/jedis maven坐标

django发送邮件的坑

django发送邮件的坑 配置django发邮件的时候本地发送时好好的,但是放到阿里云的服务器上却不能发送. 经过一系列的排查后终于发现是阿里云把25端口给封了. 后来改用smtps的方式发送,更改django的setting的邮件配置 1 EMAIL_PORT = 465 2 3 4 5 6 EMAIL_USE_SSL = True 将端口改为465 增加配置项: EMAIL_USE_SSL = True 到阿里云控制台开放465端口 重新运行django和celery 原文地址:https:

【转】Prestashop SMTP模式发送邮件客户邮件(联系我们页面)收到不的解决办法

Prestashop 一般默认使用 mail 函数发送邮件,邮件发送的IP地址就是服务器或者共享空间的IP地址.共享空间上面的网站很多,可能存在发送垃圾邮件的网站,导致共享空间的IP地址被其 他邮件服务商(gmail.hotmail等等)加入黑名单,使用mail发送的邮件全部不能够发送成功. 更换使用第三方邮件来发送邮件,Prestashop 后台设置的发送邮件模式更换成SMTP. 经过测试发现:使用SMTP发送邮件,当发件人为非SMTP账户邮箱时,发送邮件成功,但是收件人收不到邮件. 联系我们

estore商城案例(一)------用户注册&amp;邮件激活(下)

先补上昨天注册页面的验证码代码: 1 public void doGet(HttpServletRequest request, HttpServletResponse response) 2 throws ServletException, IOException { 3 BufferedImage bf=new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); 4 Graphics2D graphice=(Graphics2D

邮件激活的设计

为什么要用邮件激活用户?为了保证邮箱的正确,保证邮箱地址存在.(正则表达式只能检查邮件的格式是否正确,但不能保证邮件的真实性) http://...../UserController.ashx?action=active&username=ABC(有漏洞,因为这样不进入邮箱也可以知道如何激活) 1.需要进入邮箱之后才知道如何激活! http://...../UserController.ashx?action=active&username=ABC&activeCode=23232

用django发送异步邮件

太阳底下没有新鲜事,github是一个神奇的地方,你有什么想法,需求,点子.其实别人早就想到,而且也已经做到. 所以不要高估自己,有什么想法还是GITHUB一下,免得成了井底之娃. 这几天一直在研究python的异步发送邮件问题,django , flask 之流都是同步框架,处理IO,发送电子邮件这种耗时的操作,就有点蛋痛了. 由于基础知识不扎实,自行研究了Asyncio之流无果,在github上无赖的输入了asyn django sendmail 搜索了一把.居然找到了别人已经封闭好的源代码

Django注册-邮件激活

注册views class RegisterView(View): def get(self, request): register_form = RegisterForm() # 实例化register表单 return render(request, 'register.html', {'register_form': register_form}) def post(self, request): register_form = RegisterForm(request.POST) if

discuz x3.2设置注册邮件激活_企业邮箱发送邮件失败

在discuz x2.5邮箱设置里面已经说了很多关于邮件设置和常见问题的处理办法了,今天这里主要是说明下Discuz! 邮件发送失败排查思路,适用于任何板块的Discuz程序. Discuz! 邮件发送失败排查思路方法: 1.要确保填写的邮件信息是否正确,主要检测邮件服务器格式填写. 2.查看邮件日志文件,data/log目录下 有一个201210_SMTP.php 类似这样的文件,下面举例说明下 举例一: <?PHP exit;?>        2012-10-17 16:59:59