bifangback

bifangback-又一个典型的用户模块功能实现

2021-01-04  本文已影响0人  万州客

为了能在一个机器上跑起来服务。所以用户模块的找回密码功能,不用redis,直接用内存cache。验证码发邮箱,也不用真的邮箱,而使用console输出。

一,注释掉settings里的缓存和邮箱设置


# 自定义obtain_jwt_token登录参数验证
AUTHENTICATION_BACKENDS = (
    'account.jwt_views.CustomJwtBackend',
)
JWT_AUTH = {
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=365),
    'JWT_AUTH_HEADER_PREFIX': 'Bearer',
    'JWT_ALLOW_REFRESH': True,
}

# Django的redis缓存配置,性能要求高和有持久化要求时,可开启
# CACHES = {
#    "default": {
#        "BACKEND": "django_redis.cache.RedisCache",
#        "LOCATION": "redis://127.0.0.1:6379/1",
#        "OPTIONS": {
#            "CLIENT_CLASS": "django_redis.client.DefaultClient",
#        }
#    }
# }

# 邮件发送到控制台,而不发送到实际的邮箱
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
# 正式使用时的邮箱设置
# EMAIL_USE_SSL = True
# EMAIL_HOST = 'smtp.163.com'
# EMAIL_PORT = 465
# EMAIL_HOST_USER = 'aguncn@163.com'
# EMAIL_HOST_PASSWORD = 'xxxxxxx'
# DEFAULT_FROM_EMAIL = EMAIL_HOST_USER

SIMPLE_HISTORY_REVERT_DISABLED = True

二,DRF的APIVIEW打天下,实现用户模块功能

from random import Random
from django.contrib.auth.hashers import check_password
from django.core.mail import send_mail
from rest_framework.views import APIView
from django.core.cache import cache
from django.contrib.auth import get_user_model
from utils.ret_code import *
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema

User = get_user_model()
DEFAULT_FROM_EMAIL = 'aguncn@163.com'


def random_str(random_length=8):
    code_str = ''
    chars = 'abcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
    length = len(chars) - 1
    random = Random()
    for i in range(random_length):
        code_str += chars[random.randint(0, length)]
    return code_str


# 用户注册
class UserRegisterView(APIView):
    """
    用户注册

    参数:
    username
    password
    passwordConfirm
    email
    """
    authentication_classes = []
    permission_classes = []

    @swagger_auto_schema(
        tags=['Users']
    )
    def post(self, request, *args, **kwargs):
        req_data = request.data
        username = req_data['username']
        password = req_data['password']
        password_confirm = req_data['passwordConfirm']
        email = req_data['email']
        if password != password_confirm:
            return_dict = build_ret_data(THROW_EXP, '两次输入密码不一致!')
            return render_json(return_dict)
        if User.objects.filter(username=username):
            return_dict = build_ret_data(THROW_EXP, '用户已经存在,请重新选择用户名!')
            return render_json(return_dict)
        try:
            User.objects.create_user(username=username,
                                     password=password,
                                     email=email,
                                     is_active=True)
            return_dict = build_ret_data(OP_SUCCESS, str(req_data))
            return render_json(return_dict)
        except Exception as e:
            print(e)
            return_dict = build_ret_data(THROW_EXP, str(e))
            return render_json(return_dict)


# 更新密码
class UpdatePasswordView(APIView):
    """
    更改密码

    参数:
    username
    currentPassword
    newPassword
    newPasswordConfirm
    """

    @swagger_auto_schema(
        tags=['Users']
    )
    def post(self, request, *args, **kwargs):
        req_data = request.data
        username = req_data['username']
        login_username = request.user.username
        if login_username != username:
            return_dict = build_ret_data(THROW_EXP, '不能更新其它用户密码!')
            return render_json(return_dict)
        current_password = req_data['currentPassword']
        user = User.objects.get(username=username)
        if not check_password(current_password, user.password):
            return_dict = build_ret_data(THROW_EXP, '当前密码错误,无法更新密码!')
            return render_json(return_dict)
        if login_username != username:
            return_dict = build_ret_data(THROW_EXP, '两次输入密码不一致!')
            return render_json(return_dict)

        new_password_confirm = req_data['newPasswordConfirm']
        new_password = req_data['newPassword']
        if new_password != new_password_confirm:
            return_dict = build_ret_data(THROW_EXP, '两次输入密码不一致!')
            return render_json(return_dict)
        try:
            user.set_password(new_password)
            user.save()
            return_dict = build_ret_data(OP_SUCCESS, str(user))
            return render_json(return_dict)
        except Exception as e:
            print(e)
            return_dict = build_ret_data(THROW_EXP, str(e))
            return render_json(return_dict)


# 更新邮箱
class UpdateEmailView(APIView):
    """
    更改邮箱

    参数:
    username
    newEmail
    newEmailConfirm
    """

    @swagger_auto_schema(
        tags=['Users']
    )
    def post(self, request, *args, **kwargs):
        req_data = request.data
        username = req_data['username']
        login_username = request.user.username
        if login_username != username:
            return_dict = build_ret_data(THROW_EXP, '不能更新其它用户密码!')
            return render_json(return_dict)
        user = User.objects.get(username=username)
        new_email_confirm = req_data['newEmailConfirm']
        new_email = req_data['newEmail']
        if new_email != new_email_confirm:
            return_dict = build_ret_data(THROW_EXP, '两次输入新邮箱地址不一致!')
            return render_json(return_dict)
        try:
            user.email = new_email
            user.save()
            return_dict = build_ret_data(OP_SUCCESS, str(user))
            return render_json(return_dict)
        except Exception as e:
            print(e)
            return_dict = build_ret_data(THROW_EXP, str(e))
            return render_json(return_dict)


# 发送验证码到邮箱
class ForgetPasswordView(APIView):
    """
    发送验证码到邮箱

    参数:
    email
    """
    authentication_classes = []
    permission_classes = []
    # swagger_schema = None # 可隐藏此API的swagger文档

    @swagger_auto_schema(
        manual_parameters=[
            openapi.Parameter('email', openapi.IN_QUERY, "test manual param", type=openapi.TYPE_STRING),
        ],
        responses={
            200: openapi.Response('response description', None),
        },
        tags=['Users']
    )
    def post(self, request, *args, **kwargs):
        req_data = request.data
        email_title = "找回密码"
        random_code = random_str()
        email_body = "验证码为:{0}".format(random_code)
        email = req_data['email']
        if not User.objects.get(email=email):
            return_dict = build_ret_data(THROW_EXP, '此邮件不存在')
            return render_json(return_dict)
        # conn = get_redis_connection('default')
        # conn.set(email, random_code, ex=5)
        cache.set(email, random_code)
        email_to = [email]
        try:
            send_status = send_mail(email_title, email_body, DEFAULT_FROM_EMAIL, email_to, )
            return_dict = build_ret_data(OP_SUCCESS, str(send_status))
            return render_json(return_dict)
        except Exception as e:
            print(e)
            return_dict = build_ret_data(THROW_EXP, str(e))
            return render_json(return_dict)


# 发送新密码到邮箱
class ResetPasswordView(APIView):
    """
    发送新密码到邮箱

    参数:
    email
    verificationCode
    """
    authentication_classes = []
    permission_classes = []

    @swagger_auto_schema(
        tags=['Users']
    )
    def post(self, request, *args, **kwargs):
        req_data = request.data
        email = req_data['email']
        verification_code = req_data['verificationCode']
        email_title = "新密码,请妥善保存"
        new_password = random_str()
        email_body = "新密码为:{0}".format(new_password)
        user = User.objects.get(email=email)
        if not user:
            return_dict = build_ret_data(THROW_EXP, '此邮件不存在')
            return render_json(return_dict)
        email_to = [email]
        redis_verification_code = cache.get(email)
        print(verification_code, redis_verification_code)
        if verification_code != redis_verification_code:
            return_dict = build_ret_data(THROW_EXP, '验证码错误')
            return render_json(return_dict)
        try:
            user.set_password(new_password)
            user.save()
            send_status = send_mail(email_title, email_body, DEFAULT_FROM_EMAIL, email_to, )
            return_dict = build_ret_data(OP_SUCCESS, str(send_status))
            return render_json(return_dict)
        except Exception as e:
            print(e)
            return_dict = build_ret_data(THROW_EXP, str(e))
            return render_json(return_dict)

三,Postman测试

1,用户注册

网址:http://localhost:8000/account/register/
参数:

{
    "username": "sky",
    "password": "password",
    "passwordConfirm": "password",
    "email": "adbc@ad.com"
}

正确返回

{
    "code": 0,
    "message": "操作成功",
    "data": "{'username': 'sky', 'password': 'password', 'passwordConfirm': 'password', 'email': 'adbc@ad.com'}"
}

错误返回

{
    "code": 1000,
    "message": "抛出异常",
    "data": "用户已经存在,请重新选择用户名!"
}

2,其它的功能。

http://localhost:8000/account/register/

{
    "username": "sky",
    "password": "password",
    "passwordConfirm": "password",
    "email": "adbc@ad.com"
}

{
    "code": 0,
    "message": "操作成功",
    "data": "{'username': 'sky', 'password': 'password', 'passwordConfirm': 'password', 'email': 'adbc@ad.com'}"
}


{
    "code": 1000,
    "message": "抛出异常",
    "data": "用户已经存在,请重新选择用户名!"
}


http://localhost:8000/account/update_password/

{
    "username": "admin",
    "currentPassword": "password",
    "newPassword": "password2",
    "newPasswordConfirm": "password2"
}

{
    "code": 0,
    "message": "操作成功",
    "data": "admin"
}

{
    "code": 1000,
    "message": "抛出异常",
    "data": "当前密码错误,无法更新密码!"
}


http://localhost:8000/account/update_email/

{
    "username": "admin",
    "newEmailConfirm": "admin@demo.com",
    "newEmail": "admin@demo.com"
}

{
    "code": 0,
    "message": "操作成功",
    "data": "admin"
}

http://localhost:8000/account/forget_password/

{
    "email": "admin@demo.com"
}

Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
Subject: =?utf-8?b?5om+5Zue5a+G56CB?=
From: aguncn@163.com
To: admin@demo.com
Date: Sun, 03 Jan 2021 13:39:37 -0000
Message-ID: <160968117789.1732.12157315585525517403@LAPTOP-4H048BJN>

验证码为:d3svKRGK
-------------------------------------------------------------------------------
[03/Jan/2021 21:39:40] "POST /account/forget_password/ HTTP/1.1" 200 63


http://localhost:8000/account/reset_password/

{
    "email": "admin@demo.com",
    "verificationCode": "d3svKRGK"
}

Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
Subject: =?utf-8?b?5paw5a+G56CB77yM6K+35aal5ZaE5L+d5a2Y?=
From: aguncn@163.com
To: admin@demo.com
Date: Sun, 03 Jan 2021 13:42:27 -0000
Message-ID: <160968134723.1732.17373769924101658415@LAPTOP-4H048BJN>

新密码为:pEd3a7wu
-------------------------------------------------------------------------------
[03/Jan/2021 21:42:27] "POST /account/reset_password/ HTTP/1.1" 200 63

累了,一锅端,慢慢看。

2021-01-03 21_44_29-悬浮球.png 2021-01-03 21_40_06-C__Windows_system32_cmd.exe - python manage.py runserver.png 2021-01-03 21_32_16-悬浮球.png
上一篇下一篇

猜你喜欢

热点阅读