1. 程式人生 > 程式設計 >Django REST framwork的許可權驗證例項

Django REST framwork的許可權驗證例項

在這裡插入程式碼片# Django REST framwork的許可權驗證

一、使用者是否登入

(1)判斷使用者是否登入;

permission_classes = (IsAuthenticated,)

注意:permission_classes設定的是:驗證的是使用者是否登入、使用者是否可以操作該資料等的許可權;

許可權組合方式,目前支援:與&(and) 或|(or) 非~(not)

例如:permission_classes = (SecAdminPermission | AudAdminPermission,)

注意:使用元組 (SecAdminPermission | AudAdminPermission,)或列表[ SecAdminPermission | AudAdminPermission]都可以。

(2)設定使用者認證方式;

authentication_classes = (JSONWebTokenAuthentication,SessionAuthentication)

注意:authentication_classes設定的是:使用者可以通過哪種方式登入系統,例如:JWT或傳統的使用者名稱+密碼方式登入。

具體程式碼如下:

from rest_framework.permissions import IsAuthenticated # 判斷使用者是否登入
from rest_framework_jwt.authentication import JSONWebTokenAuthentication # jwt使用者認證
class UserFavViewset(mixins.CreateModelMixin,mixins.ListModelMixin,mixins.RetrieveModelMixin,mixins.DestroyModelMixin,viewsets.GenericViewSet):
 """
 list:
  獲取使用者收藏列表
 retrieve:
  判斷某個商品是否已經收藏
 create:
  收藏商品
 delete:
  取消收藏
 """
 # 許可權判斷:IsAuthenticated表示是否已經登入,IsOwnerOrReadOnly表示資料是不是屬於當前登入使用者
 permission_classes = (IsAuthenticated,IsOwnerOrReadOnly)
 # 使用者認證:方式一:JSONWebTokenAuthentication;方式二:SessionAuthentication
 authentication_classes = (JSONWebTokenAuthentication,SessionAuthentication)
 # 定義通過哪個引數來定位例項
 lookup_field = "goods_id" # 在詳細頁面時,搜尋goods_id來確認該商品有沒有被收藏,是在當前使用者下進行搜尋的

 def get_queryset(self):
  """獲取當前登入使用者的收藏資訊"""
  return UserFav.objects.filter(user=self.request.user)

 # 方法一:修改商品收藏數
 # def perform_create(self,serializer):
 #  """修改商品收藏數"""
 #  instance = serializer.save()
 #  goods = instance.goods
 #  goods.fav_num += 1
 #  goods.save()

 # 動態設定序列化類
 def get_serializer_class(self):
  if self.action == "list":
   return UserFavDetailSerializer
  elif self.action == "create":
   return UserFavSerializer

  return UserFavSerializer

二、使用者是否對該資料有操作許可權;

(1)自定義許可權驗證

前提:待驗證物件有user欄位;

from rest_framework import permissions

# 許可權判斷:資料是不是屬於當前登入使用者
class IsOwnerOrReadOnly(permissions.BasePermission):
 """
 Object-level permission to only allow owners of an object to edit it.
 Assumes the model instance has an `owner` attribute.
 """

 def has_object_permission(self,request,view,obj):
  # 1 只讀
  # Read permissions are allowed to any request,# so we'll always allow GET,HEAD or OPTIONS requests.
  if request.method in permissions.SAFE_METHODS: # 是不是安全的訪問方法
   return True
 # 2 寫許可權
  # Instance must have an attribute named `owner`.
  # return (obj.publisher if obj.publisher else self.fans )== request.user
  return obj.user== request.user # 判斷當前資料是不是登入使用者的資料

(2)在介面中,新增資料許可權驗證;

class UserFavViewset(mixins.CreateModelMixin,viewsets.GenericViewSet):
 """
 list:
  獲取使用者收藏列表
 retrieve:
  判斷某個商品是否已經收藏
 create:
  收藏商品
  delete:
   取消收藏
 """
 # 許可權判斷:IsAuthenticated表示是否已經登入,IsOwnerOrReadOnly表示資料是不是屬於當前登入使用者
 permission_classes = (IsAuthenticated,SessionAuthentication)
 # 設定
 lookup_field = "goods_id" # 在詳細頁面時,搜尋goods_id來確認該商品有沒有被收藏,是在當前使用者下進行搜尋的

 def get_queryset(self):
  """獲取當前登入使用者的收藏資訊"""
  return UserFav.objects.filter(user=self.request.user)

補充知識:django rest framework api授權與認證

djangorestf 官方文件 授權與認證教程

permissions.py

from rest_framework import permissions

class IsOwnerOrReadOnly(permissions.BasePermission):
  '''
  常規的授權是 只有擁有者才能編輯它
  '''

  def has_object_permission(self,obj):
    # 讀許可權 向所有請求開放
    # 所以我們總是允許get,head or options requests.
    if request.method in permissions.SAFE_METHODS:
      return True

    # 寫許可權 只給擁有者
    return obj.owner == request.user

view.py

'''基於泛型類的檢視'''
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer,UserSerializer
from rest_framework import generics
from snippets.permissions import IsOwnerOrReadOnly
from django.contrib.auth.models import User

class UserList(generics.ListAPIView):
  '''
  User表的列表api檢視 查 增 操作
  '''
  queryset = User.objects.all()
  serializer_class = UserSerializer

class UserDetail(generics.RetrieveDestroyAPIView):
  '''
  User表的詳情api檢視 查 改 刪操作
  '''
  queryset = User.objects.all()
  serializer_class = UserSerializer



class SnippetList(generics.ListCreateAPIView):
  permission_classes = [permissions.IsAuthenticatedOrReadOnly]
  queryset = Snippet.objects.all()
  serializer_class = SnippetSerializer

  def perform_create(self,serializer):
    serializer.save(owner=self.request.user)


class SnippetDetail(generics.RetrieveDestroyAPIView):
  # detail 所有人都能讀,但是隻有擁有者可以更改

  # permissions.IsAuthenticatedOrReadOnly 表示沒有認證的人有讀的許可權,認證的人有所有許可權
  # IsOwnerOrReadOnly 通過了前面的授權之後,還要通過這個授權
  # 當所有的授權都通過的時候 所有的物件例項都返回true 表示授權通過
  permission_classes = [permissions.IsAuthenticatedOrReadOnly,IsOwnerOrReadOnly]
  queryset = Snippet.objects.all()
  serializer_class = SnippetSerializer

總結:通過傳遞permission_classes 類變數 傳遞授權類,

1、請求要進行某個操作的時候 ->

2、傳遞引數將授權類列表中的多個授權類例項化得到例項化物件->

3、呼叫所有授權例項物件的has_、permission以及has_object_permission方法 ->

4、所有的返回結果都為true ->

5、該操作的授權才通過,資料操作向下繼續進行。

以上這篇Django REST framwork的許可權驗證例項就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。