我們在先前的文章中開始開發帳戶應用程序,本文將以此為基礎。它將涵蓋
我會盡力介紹盡可能多的細節,以免讓您感到無聊,但我仍然希望您熟悉 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中文網其他相關文章!