DRF JWT的用法 & Django的自定義認證類 & DRF 緩存


JWT 相關信息可參考: https://www.jianshu.com/p/576dbf44b2ae

DRF JWT 的使用方法:

1. 安裝 DRF JWT

# pip install djangorestframework-jwt 

2. 配置

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES":("rest_framework_jwt.authentication.JSONWebTokenAuthentication",)  # 全局設置的方法,也可在單個視圖中設置
}

3. 在 url 中添加相應路徑

from rest_framework.authtoken import views
from rest_framework_jwt.views import obtain_jwt_token

urlpatterns = [
    re_path(r"^api-token-auth/",views.obtain_auth_token),  # DRF 自帶的 token 認證模式;需導入
    re_path(r"^login/",obtain_jwt_token),  # jwt的認證接口(路徑可自定義任意命名)
]

 

4. 前端向 login/ 這個路徑發送請求時可進行登陸驗證;

5. 訪問需要登陸認證后才能訪問的url時,在請求頭(Header)中添加 Authorization:JWT <your_token>  (Authorization 為 name,JWT <your_token> 為 value);登陸認證成功后,自動返回給前端一個 Token

6. 使用token訪問被保護的url

# 設置某些view的權限(permission_classes)為permissions.IsAuthenticated,那么沒有提供token而訪問被保護的view是不被允許的.
# 你可以設置用戶注冊的權限為permissions.AllowAny,這樣用戶可以通過用戶名和密碼拿到token,在之后訪問被保護的view時,將token作為身份憑證發送給服務端(rest-framework會自動驗證token是否有效,如果在settings.py中做了准備中的配置的話)

7. JWT的額外設置(如過期時間)

# 在 settings 中
import datetime
JWT_AUTH = {
    'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=300),  # 設置 JWT Token 的有效時間
    'JWT_AUTH_HEADER_PREFIX': 'JWT',  # 設置 請求頭中的前綴 
}

DRF JWT 文檔:http://getblimp.github.io/django-rest-framework-jwt/

注:認證的作用是取出當前用戶

自定制 jwt 的 Token

# 注冊成功后如果想讓前端自動登陸,則需要返回給前端一個 token;所以以下為手動生成一個 token 返回給前端
from rest_framework.mixins import CreateModelMixin
from rest_framework_jwt.serializers import jwt_payload_handler,jwt_encode_handler


class UserViewset(CreateModelMixin, viewsets.GenericViewSet):
    serializer_class = UserRegSerializer
    queryset = User.objects.all()


    # 用戶注冊成功后,會在 User 表中生成一條記錄;如果想要在生成 User記錄的同時,生成一個 token ,則需要重構 CreateModelMixin 的 create() 方法
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = self.perform_create(serializer)

        # 在此處生成 token
        res_dict = serializer.data
        payload = jwt_payload_handler(user)  # user 是 User 表中生成的一條新記錄
        res_dict["token"] = jwt_encode_handler(payload)  # jwt_encode_handler(payload) 生成 token;並賦值給 res_dict["token"]
        # res_dict 還可以根據需要添加其它內容

        headers = self.get_success_headers(serializer.data)
        return Response(res_dict, status=status.HTTP_201_CREATED, headers=headers)  # 返回 res_dict

    def perform_create(self, serializer):
        return serializer.save()  # 把保存的 User 對象返回

 

自定義Django的認證類:

settings.py

# 自定義用戶認證(如:手機號、郵箱登陸;Django的認證默認是只能通過用戶名和密碼認證)
AUTHENTICATION_BACKENDS = (
    "apps.users.views.CustomBackend", # 路徑.自定義認證類
)

views.py

from django.db.models import Q
from django.contrib.auth.backends import ModelBackend
from .models import UserInfo
# Create your views here.

class CustomBackend(ModelBackend):
    """
    自定義用戶認證(如:手機號、郵箱登陸)
    自定義用戶認證時,需要把這個認證類放到 settings.py 中的 AUTHENTICATION_BACKENDS 中
    """
    def authenticate(self, request, username=None, password=None, **kwargs):  # authenticate() 這個函數中處理認證的邏輯
        """

        :param request:
        :param username: 此時 username 可以是 用戶名 或者 手機號
        :param password:
        :param kwargs:
        :return:
        """
        try:
            user = UserInfo.objects.get(Q(username=username)|Q(mobile=username))
            if user.check_password(password):  # check_password() 時會轉化為密文的形式
                return user
        except Exception as e:
            return None

 

DRF 緩存:

django的緩存在DRF中不能直接用,而應該用封閉后的緩存,如:rest_framework_extensions

1. 安裝 rest_framework_extensions

pip install drf-extensions

 

2. 配置 settings

REST_FRAMEWORK_EXTENSIONS = {
    'DEFAULT_OBJECT_CACHE_KEY_FUNC':
      'rest_framework_extensions.utils.default_object_cache_key_func',  # retrieve 方法
    'DEFAULT_LIST_CACHE_KEY_FUNC':
      'rest_framework_extensions.utils.default_list_cache_key_func',  # list 方法
}

 

3. 在視圖中添加 緩存類 CacheResponseMixin

from rest_framework_extensions.cache.mixins import CacheResponseMixin

class GoodsViewSet(CacheResponseMixin,mixins.ListModelMixin,mixins.RetrieveModelMixin,GenericViewSet): # 在對應視圖中添加 CacheResponseMixin(添加到第一個位置)
    """
    商品列表頁,分頁,過濾,搜索,排序
    list:
        所有商品列表
    retrieve:
        查看單個商品
    """
    queryset =  Goods.objects.all().order_by("pk")
    serializer_class = GoodsSerializer
    pagination_class = GoodsPagination
    filter_backends = (DjangoFilterBackend,filters.SearchFilter,filters.OrderingFilter)

    filter_class = GoodsFilter  # 過濾
    search_fields = ("name","goods_brief","goods_details")  # 搜索
    ordering_fields = ("sold_num","shop_price")  # 排序

    # 修改點擊數
    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()  # instance 是一個 Goods() 的對象
        instance.click_num += 1  # 點擊數 +1
        instance.save()
        serializer = self.get_serializer(instance)
        return Response(serializer.data)

 

4. 設置超時時間

REST_FRAMEWORK_EXTENSIONS = {
    'DEFAULT_CACHE_RESPONSE_TIMEOUT': 60 * 15  # 表示15分鍾
}

 

注: 該緩存默認使用的是 自帶的 local memory cache(程序重啟緩存即消失)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM