关于django:小白学Python使用Django实现商城邮箱验证功能

增加邮箱后端逻辑

1. 增加邮箱接口设计和定义

1.申请形式

选项 计划
申请办法 PUT
申请地址 /emails/

2.申请参数

参数名 类型 是否必传 阐明
email string 邮箱

3.响应后果:JSON

字段 阐明
code 状态码
errmsg 错误信息

2. 增加邮箱后端逻辑实现

class EmailView(View):
    """增加邮箱"""

    def put(self, request):
        """实现增加邮箱逻辑"""
        # 接管参数
        json_dict = json.loads(request.body.decode())
        email = json_dict.get('email')

        # 校验参数
        if not email:
            return http.HttpResponseForbidden('短少email参数')
        if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
            return http.HttpResponseForbidden('参数email有误')

        # 赋值email字段
        try:
            request.user.email = email
            request.user.save()
        except Exception as e:
            logger.error(e)
            return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '增加邮箱失败'})

        # 响应增加邮箱后果
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '增加邮箱胜利'})

3. 判断用户是否登录并返回JSON

重要提醒:

  • 只有用户登录时能力让其绑定邮箱。
  • 此时前后端交互的数据类型是JSON,所以须要判断用户是否登录并返回JSON给用户。

计划一:

  • 应用Django用户认证零碎提供的is_authenticated()
class EmailView(View):
    """增加邮箱"""

    def put(self, request):
        """实现增加邮箱逻辑"""
        # 判断用户是否登录并返回JSON
        if not request.user.is_authenticated():
            return http.JsonResponse({'code': RETCODE.SESSIONERR, 'errmsg': '用户未登录'})
        pass

计划二:

  • 自定义返回JSON的login_required装璜器
  • meiduo_mall.utils.views.py
def login_required_json(view_func):
    """
    判断用户是否登录的装璜器,并返回json
    :param view_func: 被装璜的视图函数
    :return: json、view_func
    """
    # 复原view_func的名字和文档
    @wraps(view_func)
    def wrapper(request, *args, **kwargs):

        # 如果用户未登录,返回json数据
        if not request.user.is_authenticated():
            return http.JsonResponse({'code': RETCODE.SESSIONERR, 'errmsg': '用户未登录'})
        else:
            # 如果用户登录,进入到view_func中
            return view_func(request, *args, **kwargs)

    return wrapper


class LoginRequiredJSONMixin(object):
    """验证用户是否登陆并返回json的扩大类"""
    @classmethod
    def as_view(cls, **initkwargs):
        view = super().as_view(**initkwargs)
        return login_required_json(view)

LoginRequiredJSONMixin的应用

class EmailView(LoginRequiredJSONMixin, View):
    """增加邮箱"""

    def put(self, request):
        """实现增加邮箱逻辑"""
        # 判断用户是否登录并返回JSON
        pass

Django发送邮件的配置

1. Django发送邮件流程剖析

send_mall()办法介绍

  • 地位:

    • django.core.mail模块提供了send_mail()来发送邮件。
  • 办法参数:

    • send_mail(subject, message, from_email, recipient_list, html_message=None)
subject 邮件题目
message 一般邮件注释,一般字符串
from_email 发件人
recipient_list 收件人列表
html_message 多媒体邮件注释,能够是html字符串

2. 筹备发邮件服务器

1.点击进入《设置》界面

2.点击进入《客户端受权明码》界面

3.开启《受权码》,并实现验证短信

4.填写《受权码》

5.实现《受权码》设置

6.配置邮件服务器

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' # 指定邮件后端
EMAIL_HOST = 'smtp.163.com' # 发邮件主机
EMAIL_PORT = 25 # 发邮件端口
EMAIL_HOST_USER = 'hmmeiduo@163.com' # 受权的邮箱
EMAIL_HOST_PASSWORD = 'hmmeiduo123' # 邮箱受权时取得的明码,非注册登录明码
EMAIL_FROM = '美多商城<hmmeiduo@163.com>' # 发件人低头

发送邮箱验证邮件

重要提醒:

  • 发送邮箱验证邮件是耗时的操作,不能阻塞美多商城的响应,所以须要异步发送邮件
  • 咱们持续应用Celery实现异步工作。

1. 定义和调用发送邮件异步工作

1.定义发送邮件工作

@celery_app.task(bind=True, name='send_verify_email', retry_backoff=3)
def send_verify_email(self, to_email, verify_url):
    """
    发送验证邮箱邮件
    :param to_email: 收件人邮箱
    :param verify_url: 验证链接
    :return: None
    """
    subject = "商城邮箱验证"
    html_message = '<p>尊敬的用户您好!</p>' \
                   '<p>感谢您应用商城。</p>' \
                   '<p>您的邮箱为:%s 。请点击此链接激活您的邮箱:</p>' \
                   '<p><a href="%s">%s<a></p>' % (to_email, verify_url, verify_url)
    try:
        send_mail(subject, "", settings.EMAIL_FROM, [to_email], html_message=html_message)
    except Exception as e:
        logger.error(e)
        # 有异样主动重试三次
        raise self.retry(exc=e, max_retries=3)

2.注册发邮件的工作:main.py

  • 在发送邮件的异步工作中,咱们用到了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工作
celery_app.autodiscover_tasks(['celery_tasks.sms', 'celery_tasks.email'])

3.调用发送邮件异步工作

# 赋值email字段
try:
    request.user.email = email
    request.user.save()
except Exception as e:
    logger.error(e)
    return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '增加邮箱失败'})

# 异步发送验证邮件
verify_url = '邮件验证链接'
send_verify_email.delay(email, verify_url)

# 响应增加邮箱后果
return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '增加邮箱胜利'})

4.启动Celery

$ celery -A celery_tasks.main worker -l info

2. 生成邮箱验证链接

1.定义生成邮箱验证链接办法

def generate_verify_email_url(user):
    """
    生成邮箱验证链接
    :param user: 以后登录用户
    :return: verify_url
    """
    serializer = Serializer(settings.SECRET_KEY, expires_in=constants.VERIFY_EMAIL_TOKEN_EXPIRES)
    data = {'user_id': user.id, 'email': user.email}
    token = serializer.dumps(data).decode()
    verify_url = settings.EMAIL_VERIFY_URL + '?token=' + token
    return verify_url

2.配置相干参数

# 邮箱验证链接
EMAIL_VERIFY_URL = 'http://www.shagncheng.site:8000/emails/verification/'

3.应用邮箱验证链接

verify_url = generate_verify_email_url(request.user)
send_verify_email.delay(email, verify_url)

验证邮箱后端逻辑

1. 验证邮箱接口设计和定义

1.申请形式

选项 计划
申请办法 GET
申请地址 /emails/verification/

2.申请参数:查问参数

参数名 类型 是否必传 阐明
token string 邮箱激活链接

3.响应后果:HTML

字段 阐明
邮箱验证失败 响应谬误提醒
邮箱验证胜利 重定向到用户核心

2. 验证链接提取用户信息

def check_verify_email_token(token):
    """
    验证token并提取user
    :param token: 用户信息签名后的后果
    :return: user, None
    """
    serializer = Serializer(settings.SECRET_KEY, expires_in=constants.VERIFY_EMAIL_TOKEN_EXPIRES)
    try:
        data = serializer.loads(token)
    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

3. 验证邮箱后端逻辑实现

验证邮箱的外围:就是将用户的email_active字段设置为True

class VerifyEmailView(View):
    """验证邮箱"""

    def get(self, request):
        """实现邮箱验证逻辑"""
        # 接管参数
        token = request.GET.get('token')

        # 校验参数:判断token是否为空和过期,提取user
        if not token:
            return http.HttpResponseBadRequest('短少token')

        user = check_verify_email_token(token)
        if not user:
            return http.HttpResponseForbidden('有效的token')

        # 批改email_active的值为True
        try:
            user.email_active = True
            user.save()
        except Exception as e:
            logger.error(e)
            return http.HttpResponseServerError('激活邮件失败')

        # 返回邮箱验证后果
        return redirect(reverse('users:info'))

关注公众号:测试老憨,回复:商城,获取实现我的项目代码

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理