[英]Django rest_framework forgot password
I'm newbie in Django I have a trouble with this: I've already make API for 'request-reset-email', 'password-reset' and 'password-reset-complete' Here are the code: file: urls.py我是 Django 的新手 我遇到了麻烦:我已经为“请求重置电子邮件”、“密码重置”和“密码重置完成”制作了 API 这是代码:文件:网址。 py
from django.urls import path
from .views import *
from django.contrib.auth import views as auth_view
from rest_framework_simplejwt.views import (
TokenObtainSlidingView,
TokenRefreshSlidingView,
)
urlpatterns=[
path('register/', RegisterView.as_view(), name="register"),
path('login/', LoginAPIView.as_view(), name="login"),
path('email-verify/', VerifyEmail.as_view(), name="email-verify"),
path('token/refresh/', TokenRefreshSlidingView.as_view(), name='token_refresh'),
path('request-reset-email/',RequestPasswordResetEmail.as_view(), name='request-reset-email'),
path('password-reset/<uidb64>/<token>/',PasswordTokenCheckAPIView.as_view(),name='password-reset'),
path('password-reset-complete/',SetNewPasswordAPIView.as_view(),name='password-reset-complete')
]
file Views.py:文件 Views.py:
from django.shortcuts import render
from rest_framework import exceptions, generics, serializers
from rest_framework.response import Response
from rest_framework import status
from .models import *
from .serializers import *
from rest_framework_simplejwt.tokens import RefreshToken
from .utils import *
from django.contrib.sites.shortcuts import get_current_site
from django.urls import reverse
import jwt
from django.conf import settings
from django.contrib.auth.tokens import PasswordResetTokenGenerator
from django.utils.encoding import smart_str, force_str, smart_bytes, DjangoUnicodeDecodeError
from django.utils.http import urlsafe_base64_decode, urlsafe_base64_encode
# Create your views here.
class RegisterView(generics.GenericAPIView):
queryset = User.objects.all()
serializer_class=RegisterSerializer
def post(self, request):
user = request.data
serializer = self.serializer_class(data=user)
serializer.is_valid(raise_exception=True)
serializer.save()
user_data = serializer.data
user= User.objects.get(email=user_data['email'])
token=RefreshToken.for_user(user).access_token
current_site=get_current_site(request).domain
realtivelink = reverse('email-verify')
absurl='http://'+current_site+realtivelink+"?token="+ str(token)
email_body='Hi '+ user.email+ ' Use link below to verify your email \n' + absurl
data={'email_body':email_body,'to_email':user.email,'email_subject':'Verify your email'}
Util.send_email(data)
return Response(user_data,status= status.HTTP_201_CREATED)
class VerifyEmail(generics.GenericAPIView):
def get(self,request):
token= request.GET.get('token')
try:
payload=jwt.decode(token,settings.SECRET_KEY,algorithms='HS256')
user=User.objects.get(id=payload['user_id'])
if not user.is_verified:
user.is_verified=True
user.save()
return Response({'email':'Successfully activated'},status= status.HTTP_200_OK)
except jwt.ExpiredSignatureError as indentifier:
return Response({'email':'Activation expired'},status= status.HTTP_400_BAD_REQUEST)
except jwt.exceptions.DecodeError as indentifier:
return Response({'email':'Invalid token'},status= status.HTTP_400_BAD_REQUEST)
class LoginAPIView(generics.GenericAPIView):
queryset = User.objects.all()
serializer_class = LoginSerializers
def post(self, request):
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
return Response(serializer.data,status=status.HTTP_200_OK )
class RequestPasswordResetEmail(generics.GenericAPIView):
queryset = User.objects.all()
serializer_class=ResetPasswordViaEmailSerializer
def post(self, request):
serializer = self.serializer_class(data=request.data)
email = request.data['email']
if User.objects.filter(email=email).exists():
user = User.objects.get(email=email)
uidb64 = urlsafe_base64_encode(smart_bytes(user.id) )
token = PasswordResetTokenGenerator().make_token(user)
current_site=get_current_site(request=request).domain
realtivelink = reverse('password-reset',kwargs={'uidb64':uidb64,'token':token})
absurl='http://'+current_site+realtivelink
email_body='Hi, \nUse link below to reset your password \n' + absurl
data={'email_body':email_body,'to_email':user.email,'email_subject':'Reset your password'}
Util.send_email(data)
return Response({'successfully':'check your email to reset your password'},status=status.HTTP_200_OK)
class PasswordTokenCheckAPIView(generics.GenericAPIView):
def get(self, request, uidb64,token):
try:
id= smart_str(urlsafe_base64_decode(uidb64))
user= User.objects.get(id=id)
if not PasswordResetTokenGenerator().check_token(user,token):
return Response({'error':'token is not valid, please check the new one'},status=status.HTTP_401_UNAUTHORIZED)
return Response({'sucess':True, 'message':'Credential Valid','uidb64':uidb64, 'token':token},status=status.HTTP_200_OK)
except DjangoUnicodeDecodeError as indentifier:
return Response({'error':'token is not valid, please check the new one'},status=status.HTTP_401_UNAUTHORIZED)
class SetNewPasswordAPIView(generics.GenericAPIView):
queryset = User.objects.all()
serializer_class=ResetPassWordSerializer
def patch(self, request):
serializer=self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
return Response({'sucess':True, 'message':'Password is reset successfully'},status=status.HTTP_200_OK)
APIs've already worked. API 已经发挥作用。 But I want to make the "PasswordTokenCheckAPIView" have a templete for user to enter the new password and confirm it.但我想让“PasswordTokenCheckAPIView”有一个模板供用户输入新密码并确认。 So, could you please to give me some way to do this?那么,你能给我一些方法吗? I've tried to use django.contrib.auth.PasswordResetConfirmView, it appears the template when I click the link I received in mail, but when I confirm change password, there is error我尝试使用 django.contrib.auth.PasswordResetConfirmView,当我点击我在邮件中收到的链接时它会出现模板,但是当我确认更改密码时,出现错误
from django.urls import path
from .views import *
from django.contrib.auth import views as auth_view
from rest_framework_simplejwt.views import (
TokenObtainSlidingView,
TokenRefreshSlidingView,
)
urlpatterns=[
path('register/', RegisterView.as_view(), name="register"),
path('login/', LoginAPIView.as_view(), name="login"),
path('email-verify/', VerifyEmail.as_view(), name="email-verify"),
path('token/refresh/', TokenRefreshSlidingView.as_view(), name='token_refresh'),
path('request-reset-email/',RequestPasswordResetEmail.as_view(), name='request-reset-email'),
path('password-reset/<uidb64>/<token>/',auth_view.PasswordResetConfirmView.as_view(),name='password-reset'),
path('password_reset_complete/',auth_view.PasswordResetCompleteView.as_view(),name='password-reset-complete')
]
the error: Reverse for 'password_reset_complete' not found.错误:找不到“password_reset_complete”的反向。 'password_reset_complete' is not a valid view function or pattern name. 'password_reset_complete' 不是有效的视图 function 或模式名称。
Thank you very much!非常感谢你!
Change改变
path('password_reset_complete/',auth_view.PasswordResetCompleteView.as_view(),name='password-reset-complete')
to到
path('password_reset_complete/',auth_view.PasswordResetCompleteView.as_view(),name='password_reset_complete')
Django reverse checks for name in the path. Django 反向检查路径中的名称。
Can you share your Serializers pls你能分享你的序列化程序吗
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.