我们在之前的文章中开始开发帐户应用程序,本文将以此为基础。它将涵盖
我会尽力介绍尽可能多的细节,以免让您感到无聊,但我仍然希望您熟悉 Python 和 Django 的某些方面。
最终版本的源代码可以在https://github.com/saad4software/alive-diary-backend
感兴趣的话可以查看之前的文章!
忘记密码请求如何运作?流程应遵循以下步骤
因此,我们需要一个 API 来获取电子邮件地址、创建激活码并将其发送给用户,与重新发送代码 API 相同。
我们还需要另一个 API 来获取电子邮件、激活码和新密码来重置密码。
从重新发送代码 API 开始现在听起来是个好主意。
一如既往,让我们从序列化器开始
class SendCodeSerializer(serializers.Serializer): username = serializers.CharField(required=True) def validate_username(self, value): if not is_valid_email(value): raise serializers.ValidationError("invalid_email") verification_query = get_user_model().objects.filter(username=value).exists() if not verification_query: raise serializers.ValidationError("invalid_username") return value
app_account/serializers.py
这是一个通用序列化程序,只有一个字段,即用户名,我们正在检查以确保它是有效的电子邮件地址,并且用户已在系统中注册。
现在来看看
class AccountSendCodeView(APIView): permission_classes = () renderer_classes = [CustomRenderer, BrowsableAPIRenderer] @swagger_auto_schema(request_body=SendCodeSerializer) def post(self, request, *args, **kwargs): serializer = SendCodeSerializer(data=request.data) if not serializer.is_valid(): raise APIException(serializer.errors) user = get_user_model().objects.filter(username=serializer.validated_data.get("username")).first() code = VerificationCode(user=user, email=user.username) code.save() send_mail( 'Password Reset Code', 'Your password reset code is ' + str(code.code), f'AliveDiary<{settings.EMAIL_SENDER}>', [user.username], fail_silently=False, ) return Response("success")
app_account/views.py
视图首先验证请求,然后获取用户并为其创建代码实例。最后通过电子邮件将代码发送给用户。
最后是网址
urlpatterns = [ path('register/', AccountRegisterView.as_view()), path('activate/', AccountActivateView.as_view()), path('login/', AccountLoginView.as_view()), path('refresh/', AccountRefreshTokenView.as_view()), path('code/', AccountSendCodeView.as_view()), #new path('password/', AccountChangePasswordView.as_view()), ]
app_account/urls.py
我们现在可以在 swagger 上测试它
序列化器应包含用户名、发送的代码和新密码;它应该检查以确保它是有效的用户名和代码,有点像
class ForgotPasswordSerializer(serializers.Serializer): username = serializers.CharField(required=True) code = serializers.CharField(required=True) new_password = serializers.CharField(required=True) def validate(self, data): verification_query = VerificationCode.objects.filter( user__username=data['username'], ).order_by('-id') if not verification_query.exists(): raise serializers.ValidationError("no_code") code = verification_query[0] if str(code.code) != str(data['code']): raise serializers.ValidationError("invalid_code") return data
app_account/serializers.py
所有字段都是必需的,我们使用验证函数来同时验证用户名和代码。如果该用户没有即时代码,我们会引发验证错误,如果发送的代码与即时代码值不匹配,我们会通过引发“invalid_code”验证错误来通知用户。
对于视图,我们需要首先验证序列化器
class SendCodeSerializer(serializers.Serializer): username = serializers.CharField(required=True) def validate_username(self, value): if not is_valid_email(value): raise serializers.ValidationError("invalid_email") verification_query = get_user_model().objects.filter(username=value).exists() if not verification_query: raise serializers.ValidationError("invalid_username") return value
app_account/views.py
如果序列化器无效,我们会引发一个带有序列化器错误的 API 异常,如果有效,我们将使用序列化器数据查询验证瞬间。请注意,此查询始终存在,并且发送的代码与验证即时代码值相同,因为此查询已经通过了序列化器检查。
然后我们从数据库中删除验证实例,并使用序列化器中的“new_password”值更新用户密码
最后,让我们更新 URL 文件
class AccountSendCodeView(APIView): permission_classes = () renderer_classes = [CustomRenderer, BrowsableAPIRenderer] @swagger_auto_schema(request_body=SendCodeSerializer) def post(self, request, *args, **kwargs): serializer = SendCodeSerializer(data=request.data) if not serializer.is_valid(): raise APIException(serializer.errors) user = get_user_model().objects.filter(username=serializer.validated_data.get("username")).first() code = VerificationCode(user=user, email=user.username) code.save() send_mail( 'Password Reset Code', 'Your password reset code is ' + str(code.code), f'AliveDiary<{settings.EMAIL_SENDER}>', [user.username], fail_silently=False, ) return Response("success")
app_account/urls.py
让我们首先为用户模型创建一个序列化器,它看起来像这样
urlpatterns = [ path('register/', AccountRegisterView.as_view()), path('activate/', AccountActivateView.as_view()), path('login/', AccountLoginView.as_view()), path('refresh/', AccountRefreshTokenView.as_view()), path('code/', AccountSendCodeView.as_view()), #new path('password/', AccountChangePasswordView.as_view()), ]
app_account/serializers.py
它是一个模型序列化器,我们选择了用户模型并列出了要序列化的字段。
转向视图,我们需要一个允许用户通过 GET 请求获取用户详细信息并通过 POST 请求更新用户详细信息的视图,它看起来有点像
class ForgotPasswordSerializer(serializers.Serializer): username = serializers.CharField(required=True) code = serializers.CharField(required=True) new_password = serializers.CharField(required=True) def validate(self, data): verification_query = VerificationCode.objects.filter( user__username=data['username'], ).order_by('-id') if not verification_query.exists(): raise serializers.ValidationError("no_code") code = verification_query[0] if str(code.code) != str(data['code']): raise serializers.ValidationError("invalid_code") return data
app_account/views.py
和网址
class AccountForgotPasswordView(APIView): permission_classes = () renderer_classes = [CustomRenderer, BrowsableAPIRenderer] @swagger_auto_schema(request_body=ForgotPasswordSerializer) def post(self, request, *args, **kwargs): serializer = ForgotPasswordSerializer(data=request.data) if not serializer.is_valid(): raise APIException(serializer.errors) verification_query = VerificationCode.objects.filter( user__username=serializer.validated_data.get('username'), code=serializer.validated_data.get('code') ).order_by('-id') verification_query.delete() user = get_user_model().objects.filter( username=serializer.validated_data.get('username'), ).first() user.set_password(serializer.validated_data.get('new_password')) user.save() return Response("success")
app_account/urls.py
就是这样!让我们用 Swagger 来测试一下,打开 http://localhost:8555/swagger/ 并使用登录名来获取有效的令牌。为了测试任何授权请求,我们必须单击锁定 ?图标,任何 swagger 中的锁图标,并为令牌提供“Bearer”前缀,有点像“Bearer eyJhbGc...”
现在测试详细信息 API 应返回如图所示的帐户详细信息
就是这样!恭喜,您拥有一个功能齐全的帐户管理应用程序,只需进行最少的修改即可在任何 Django 应用程序中使用
您认为它还需要其他功能吗?请提出建议!
我们将在下一篇文章中回到主应用程序,所以
敬请期待?
以上是Django 帐户管理应用程序(忘记密码和帐户详细信息的详细内容。更多信息请关注PHP中文网其他相关文章!