1. from django.http import JsonResponse
    2. # 定义一个装饰器,验证是否已经登陆
    3. def login_required(func):
    4. # func:是视图函数
    5. def wrapper(request, *args, **kwargs):
    6. # 添加功能代码
    7. if request.user.is_authenticated:
    8. return func(request, *args, **kwargs)
    9. else:
    10. return JsonResponse({'code': 400, 'errmsg': '您未登陆!'}, status=401)
    11. return wrapper
    1. from shop.utils.views import login_required
    2. from django.utils.decorators import method_decorator
    3. class UserInfoView(View):
    4. @method_decorator(login_required)
    5. def get(self, request):
    6. # 1、获取用户对象
    7. user = request.user
    8. # 2、构造响应数据返回
    9. return JsonResponse({
    10. 'code': 0,
    11. 'errmsg': 'ok',
    12. 'info_data': {
    13. 'username': user.username,
    14. 'mobile': user.mobile,
    15. 'email': user.email, # email模型没写,暂时先注释
    16. 'email_active': user.email_active # email模型没写,暂时先注释
    17. }
    18. })
    1. re_path(r'^info/$', UserInfoView.as_view()),
    1. from django.db import models
    2. from django.contrib.auth.models import AbstractUser
    3. from itsdangerous import TimedJSONWebSignatureSerializer,BadSignature
    4. from django.conf import settings
    5. class User(AbstractUser):
    6. mobile = models.CharField(max_length=11, unique=True, verbose_name='手机号')
    7. email_active = models.BooleanField(default=False, verbose_name='邮箱验证状态')
    8. class Meta:
    9. db_table = 'tb_users'
    10. verbose_name = '用户'
    11. verbose_name_plural = verbose_name
    12. def __str__(self):
    13. return self.username
    14. # 用户模型类中封装该方法
    15. def generate_verify_email_url(self):
    16. """
    17. 生成当前用户的令牌;并且拼接邮箱确认的连接;
    18. :return: 返回确认连接
    19. """
    20. serializer = TimedJSONWebSignatureSerializer(secret_key=settings.SECRET_KEY)
    21. user_info = {'user_id': self.id, 'email': self.email}
    22. token = serializer.dumps(user_info) # b'....'
    23. verify_url = settings.EMAIL_VERIFY_URL + token.decode()
    24. return verify_url
    25. # 校验token值,返回用户对象 @staticmethod 不访问实例属性、不调用实例方法
    26. @staticmethod
    27. def check_verify_email_token(token):
    28. """
    29. 校验token值
    30. :param token: token值
    31. :return: 用户对象 或 None
    32. """
    33. serializer = TimedJSONWebSignatureSerializer(secret_key=settings.SECRET_KEY)
    34. try:
    35. user_info = serializer.loads(token)
    36. except BadSignature as e:
    37. print(e)
    38. return None
    39. user_id = user_info.get('user_id')
    40. try:
    41. user = User.objects.get(pk=user_id)
    42. except User.DoesNotExist as e:
    43. print(e)
    44. return None
    45. return user
    1. class UserInfoView(View):
    2. @method_decorator(login_required)
    3. def get(self, request):
    4. # 1、获取用户对象
    5. user = request.user
    6. # 2、构造响应数据返回
    7. return JsonResponse({
    8. 'code': 0,
    9. 'errmsg': 'ok',
    10. 'info_data': {
    11. 'username': user.username,
    12. 'mobile': user.mobile,
    13. 'email': user.email, # email模型添加后写
    14. 'email_active': user.email_active # email模型添加后写
    15. }
    16. })
    1. # 发送短信的相关设置, 这些设置是当用户没有发送相关字段时, 默认使用的内容:
    2. # 发送短信必须进行的设置:
    3. EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
    4. # 我们使用的 smtp服务器 地址
    5. EMAIL_HOST = 'smtp.163.com'
    6. # 端口号
    7. EMAIL_PORT = 25 # 或者 465/587是设置了 SSL 加密方式 163邮箱465/587有限制,QQ邮箱,可以用。
    8. # 下面的内容是可变的, 随后台设置的不同而改变:
    9. # 发送邮件的邮箱
    10. EMAIL_HOST_USER = '你的163邮箱'
    11. # 在邮箱中设置的客户端授权密码
    12. EMAIL_HOST_PASSWORD = '授权码' # 如果重新设置了新的授权码,直接使用最新的授权码即可
    13. EMAIL_USE_TLS = True # 这里必须是 True,否则发送不成功
    14. # 收件人看到的发件人
    15. EMAIL_FROM = '阿尔法商城<你的163邮箱>'
    16. # 邮箱验证链接
    17. EMAIL_VERIFY_URL = 'http://127.0.0.1/success_verify_email.html?token='
    1. from django.core.mail import send_mail
    2. from django.conf import settings
    3. from celery_tasks.main import app
    4. @app.task(name='send_verify_email')
    5. def send_verify_email(to_email, verify_url):
    6. subject = '阿尔法商城邮箱验证'
    7. html_message = '<p>尊敬的用户您好!</p>' \
    8. '<p>感谢您使用阿尔法商城。</p>' \
    9. '<p>您的邮箱为:%s 。请点击此链接激活您的邮箱:</p>' \
    10. '<p><a href="%s">%s<a></p>' % (to_email, verify_url, verify_url)
    11. send_mail(
    12. subject,
    13. '',
    14. settings.EMAIL_FROM,
    15. [to_email],
    16. html_message=html_message
    17. )
    1. import os
    2. os.environ.setdefault(
    3. 'DJANGO_SETTINGS_MODULE',
    4. 'settings.dev_settings',
    5. )
    6. from celery import Celery
    7. app = Celery("shop")
    8. app.config_from_object('celery_tasks.config')
    9. app.autodiscover_tasks([
    10. 'celery_tasks.sms',
    11. 'celery_tasks.email',
    12. ])
    1. from celery_tasks.email.tasks import send_verify_email
    2. # 更新邮箱
    3. class EmailView(View):
    4. @method_decorator(login_required)
    5. def put(self, request):
    6. # 1、提取参数
    7. data = json.loads(request.body.decode())
    8. email = data.get('email')
    9. # 2、校验参数
    10. if not email:
    11. return JsonResponse({'code': 400, 'errmsg': '缺少email'})
    12. if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
    13. return JsonResponse({'code': 400, 'errmsg': '邮箱格式有误!'})
    14. # 3、数据处理(部分更新) ———— 更新邮箱
    15. user = request.user
    16. try:
    17. user.email = email
    18. user.email_active = False
    19. user.save()
    20. except Exception as e:
    21. print(e)
    22. # ======发送邮箱验证邮件=======
    23. verify_url = user.generate_verify_email_url()
    24. send_verify_email.delay(email, verify_url) # 异步调用!
    25. # 4、构建响应
    26. return JsonResponse({'code': 0, 'errmsg': 'ok'})
    1. class VerifyEmailView(View):
    2. def put(self, request):
    3. # 1、提取查询字符串中token
    4. token = request.GET.get('token')
    5. # 2、校验token
    6. user = User.check_verify_email_token(token)
    7. if not user:
    8. return JsonResponse({'code': 400, 'errmsg': '验证邮件无效!'})
    9. # 3、如果token有效,把邮箱的激活状态设置为True
    10. user.email_active = True
    11. user.save()
    12. return JsonResponse({'code': 0, 'errmsg': '邮箱激活成功!'})