首頁 >後端開發 >Python教學 >Django 帳戶管理應用程式(登入和變更密碼

Django 帳戶管理應用程式(登入和變更密碼

DDD
DDD原創
2024-11-26 06:24:09167瀏覽

您對這篇文章有什麼期望?

我們在上一篇文章中開始開發帳戶應用程序,本文將以此為基礎。它將涵蓋

  • 用於登入、刷新令牌和更改密碼請求的序列化器
  • 相同 API 的視圖、登入、刷新令牌和更改密碼
  • 當然還有網址。

我會盡力介紹盡可能多的細節,以免讓您感到無聊,但我仍然希望您熟悉 Python 和 Django 的某些方面。

最終版本的原始碼可以在https://github.com/saad4software/alive-diary-backend

系列訂購

有興趣的話可以查看之前的文章!

  1. 從頭開始的人工智慧專案、創意、Alive 日記
  2. 用 Google AI Studio 證明它是可行的
  3. Django API 專案設定
  4. Django 帳戶管理應用程式(一)、註冊與啟動
  5. Django 帳戶管理應用程式(2)、登入和更改密碼(你在這裡?)

快速登入和刷新 API!

好吧,如果你很趕時間並且沒有一些複雜的用戶管理和用戶角色系統,你可以簡單地按照SimpleJWT文檔中的說明進行操作,你不必創建序列化器或視圖,只需編輯URL文件如下

from django.urls import path, include
from .views import *
from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
)

urlpatterns = [
    path('register/', AccountRegisterView.as_view()),
    path('activate/', AccountActivateView.as_view()),
    path('login/', TokenObtainPairView.as_view()),
    path('refresh/', TokenRefreshView.as_view()),
]

app_account/urls.py

一切順利,現在使用
運行應用程式

python manage.py runserver 0.0.0.0:8555

開啟 URL http://localhost:8555/api/account/login/ 將允許您登錄,而 http://localhost:8555/api/account/refresh/ 將允許您刷新代幣

Django accounts management app ( login and change password

很好又簡單,但是如果我們需要自訂令牌回應怎麼辦?實際上,我希望此回應遵循我們在上一篇文章中建立的相同回應模式,並取得 UI 的角色欄位以區分普通使用者和管理員,如何做到這一點?

自訂登入API

為了獲得遵循我們模式的回應,我們可以簡單地建立一個繼承自 TokenObtainPairSerializer 的空序列化器

from rest_framework_simplejwt.serializers import TokenObtainPairSerializer

class LoginSerializer(TokenObtainPairSerializer):
    pass

app_account/serializers.py

並將其傳遞給使用我們的自訂渲染器的登入視圖

from rest_framework_simplejwt.views import TokenViewBase

class AccountLoginView(TokenViewBase):
    serializer_class = LoginSerializer
    renderer_classes = [CustomRenderer, BrowsableAPIRenderer]

app_account/views.py

登入回應現在應該遵循我們的架構。只需確保更新 URL 文件以指向我們的自訂登入視圖

from django.urls import path, include
from .views import *
from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
)

urlpatterns = [
    path('register/', AccountRegisterView.as_view()),
    path('activate/', AccountActivateView.as_view()),
    path('login/', AccountLoginView.as_view()),
    path('refresh/', TokenRefreshView.as_view()),
]

app_account/urls.py

Django accounts management app ( login and change password

加入角色欄位有點棘手,最簡單的方法是覆蓋序列化器中的驗證函數,在簡單的 JWT 的幫助下,我們得到了

from django.urls import path, include
from .views import *
from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
)

urlpatterns = [
    path('register/', AccountRegisterView.as_view()),
    path('activate/', AccountActivateView.as_view()),
    path('login/', TokenObtainPairView.as_view()),
    path('refresh/', TokenRefreshView.as_view()),
]

app_account/serializers.py

我們首先取得使用者對象,如果它不存在或密碼不匹配,則會引發錯誤並顯示「invalid_credentials」訊息,然後我們確保使用者處於活動狀態,最後,我們得到令牌並建立回應。現在就來嘗試吧!

Django accounts management app ( login and change password

我知道對於一個簡單的目標來說看起來太忙碌了!但它使我們能夠控制驗證行為並允許我們添加任何其他欄位。讓我們加入使用者資訊

python manage.py runserver 0.0.0.0:8555

app_account/serializers.py

自訂刷新令牌API

再做一次,做得更好!

from rest_framework_simplejwt.serializers import TokenObtainPairSerializer

class LoginSerializer(TokenObtainPairSerializer):
    pass

app_account/serializer.py

這將為我們提供新的存取和刷新令牌,以及角色和使用者數據,如果我們不需要額外的字段,我們可以簡單地使用繼承自TokenRefreshSerializer 的空序列化器類別(帶有pass)
刷新視圖應該如下圖

from rest_framework_simplejwt.views import TokenViewBase

class AccountLoginView(TokenViewBase):
    serializer_class = LoginSerializer
    renderer_classes = [CustomRenderer, BrowsableAPIRenderer]

app_account/views.py

它使用我們新的 RefreshTokenSerializer 和 CustomRenderer,不要忘記更新 URL 檔案

from django.urls import path, include
from .views import *
from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
)

urlpatterns = [
    path('register/', AccountRegisterView.as_view()),
    path('activate/', AccountActivateView.as_view()),
    path('login/', AccountLoginView.as_view()),
    path('refresh/', TokenRefreshView.as_view()),
]

app_account/urls.py
偉大的!測試它應該會回傳類似這樣的內容

Django accounts management app ( login and change password

修改密碼API

一如既往。讓我們從序列化器開始

from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from django.contrib.auth import get_user_model

class LoginSerializer(TokenObtainPairSerializer):

    def validate(self, attrs):
        username = attrs['username']
        user = get_user_model().objects.filter(username=username).first()

        if not user or not user.check_password(attrs['password']):
            raise serializers.ValidationError("invalid_credentials")

        if not user.is_active:
            raise serializers.ValidationError("not_active")

        refresh = self.get_token(user)

        data = {
            'refresh': str(refresh),
            'access': str(refresh.access_token),
            'role': user.role,
        }

        return data

app_account/serializers.py

它是一個自訂序列化器,具有兩個必要的字元欄位。移動到視圖

class UserSerializer(serializers.ModelSerializer):

    class Meta:
        model = get_user_model()
        fields = (
            'first_name', 
            'last_name', 
            'username', 
            'country_code', 
            'expiration_date',
            'hobbies',
            'job',
            'bio',
            'role',
        )
        read_only_fields = ['username', 'role',  'expiration_date']


class LoginSerializer(TokenObtainPairSerializer):

    def validate(self, attrs):
        username = attrs['username']
        user = get_user_model().objects.filter(username=username).first()

        if not user or not user.check_password(attrs['password']):
            raise serializers.ValidationError("invalid_credentials")

        if not user.is_active:
            raise serializers.ValidationError("not_active")

        refresh = self.get_token(user)

        data = {
            'refresh': str(refresh),
            'access': str(refresh.access_token),
            'user': UserSerializer(user).data,
            'role': user.role,
        }

        return data

app_account/views.py

這個請求需要經過驗證的用戶,所以我們使用 IsAuthenticated 作為權限類,當然,我們使用了我們自訂的渲染器類別。對於 POST 請求,我們首先確保請求滿足序列化器類型,然後檢查密碼有效性(如果有效);我們更改它並保存新的使用者模型

在瀏覽器中開啟 http://localhost:8555/api/account/password/ 看起來像這樣

Django accounts management app ( login and change password

由於它是經過驗證的視圖,因此需要使用 BrowsableAPIRenderer 不支援的不記名令牌。
為了測試這個(以及每個經過身份驗證的請求),我們有兩個選項之一

  • 使用像postman或insomnia這樣的IDE(我個人比較喜歡Insomnia,因為它仍然不會強迫我登入)
  • 或使用 swagger

如果你選擇第一個路徑,可以忽略下一篇文章!下一篇文章將引導您在 Django 專案中實現 Swagger

敬請期待?

以上是Django 帳戶管理應用程式(登入和變更密碼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn