邮箱找回密码实现
思路:
点击邮箱找回:前端给后端服务器发送请求
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> 您好,请点击<a href=%s style="text-decoration: none">重置密码链接</a>,完成重置密码,有效时间10分钟。</p><br>
<p> 如果您无法打开该链接,请复制%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)