邮箱找回密码实现

邮箱找回密码实现

思路:

点击邮箱找回:前端给后端服务器发送请求
get:http://127.0.0.1:8000/api/v1/email?email=7777777777@qq.com
            
后端发送邮件:邮件内容包含修改密码页面的连接,url拼接:加密token(包含email信息)

邮件内点击连接:给前端服务器发送请求,输入密码页面
get:http://106.53.251.122:3004/#/resetPwd?email_token=加密token(包含email信息)

前端页面填写密码:给后端服务器发送请求
post:http://127.0.0.1:8000/api/v1/set_password    
参数:加密token(包含email信息)

后端修改密码

1 生成 token

"""生成token"""
import jwt
import datetime
from linde import settings
from jwt import exceptions

SALT = settings.SECRET_KEY
TOKEN_EXPIRED_TIME = settings.TOKEN_EXPIRED_TIME


def get_token(data, exp):
    """构造token"""
    headers = {
        'typ': 'jwt',
        'alg': 'HS256'
    }
    # 构造payload
    payload = {
        'exp': datetime.datetime.utcnow() + datetime.timedelta(seconds=exp["seconds"]),  # 过期时间
        'data': data  # 数据
    }
    jwt_token = jwt.encode(payload=payload, key=SALT, algorithm="HS256", headers=headers).decode('utf-8')
    return jwt_token


def parse_payload(token):
    """
    对token进行和发行校验并获取payload
    """
    try:
        parse_result = jwt.decode(token, SALT, True)
    except exceptions.ExpiredSignatureError:
        parse_result = 0
    return parse_result


if __name__ == '__main__':
    result = get_token({'email':'qqq'}, TOKEN_EXPIRED_TIME)
    print(result)
    payload = parse_payload(result)
    print(payload)

2 后端视图

# django提供的发送邮件服务
from django.core.mail import send_mail

class EmailView(APIView):
    """
        邮箱找回密码
    """
    def post(self, request, version):
        email = request.data.get('email')
        if not email:
            resp = unified_response(code=status.InputErr, message='缺少邮箱信息')
            return Response(resp)
        user_obj = UserInfo.objects.filter(email=email).first()
        if not user_obj:
            resp = unified_response(code=status.Usernotfound, message='该用户不存在')
            return Response(resp)
            
        email_token = get_token({'email': email}, settings.TOKEN_EXPIRED_TIME)
        url = settings.VUE_URL + '?email_token=%s' % email_token
        subject = '找回密码'
        html_message = '''
<div>
    <p>尊敬的用户:</p ><br>
    <p>&nbsp;&nbsp;&nbsp;&nbsp;您好,请点击<a href=%s style="text-decoration: none">重置密码链接</a>,完成重置密码,有效时间10分钟。</p><br>
    <p>&nbsp;&nbsp;&nbsp;&nbsp;如果您无法打开该链接,请复制%s 到浏览器中进行操作。</p ></br>
</div>
    ''' % (url, url)
        try:
            send_mail(subject, message=None, html_message=html_message, from_email=settings.EMAIL_HOST_USER,
                      recipient_list=[email, ])
            logger.info('发送了找回密码邮件:%s'%email)
            resp = unified_response()
        except Exception:
            resp = unified_response(code=status.InputErr, message='无法给该地址发送邮件')
        return Response(resp)

    def put(self, request, version):
        """重置密码"""
        email_token = request.data.get('email_token')
        new_password = request.data.get('new_password')
        re_password = request.data.get('re_password')
        # {'exp': 1657015855, 'data': {'email': 'qqq'}}
        email_payload = parse_payload(email_token)
        if email_payload != 0:
            email = parse_payload(email_token).get('data').get('email')
            if new_password == re_password:
                user_obj = models.UserInfo.objects.filter(email=email).first()
                if user_obj:
                    user_obj.set_password(new_password)
                    user_obj.save()
                    resp = unified_response()
                else:
                    resp = unified_response(code=status.Usernotfound, message='邮箱不正确,用户不存在')
            else:
                resp = unified_response(code=status.PasswordDefErr, message='两次密码不一致')
        else:
            resp = unified_response(code=status.PermissionErr, message='token过期')
        return Response(resp)
原文地址:https://www.cnblogs.com/pythonwl/p/14271299.html