1. 程式人生 > 其它 >drf之認證,頻率和許可權

drf之認證,頻率和許可權

1 認證

# 登陸介面---》登陸成功,只要給前端返回json格式字串---》字串中帶一個隨機字串
# 認證---》登陸認證---》判斷使用者是否登入了---》前後端分離---》用不到cookie---》攜帶隨機字串過來---》通過判斷隨機字串判斷這個人是否登入了

# 登陸介面編寫步驟
	-建立表:User表,一對一UserToken表
  -前端傳入使用者名稱,密碼---》User表中查,如果能查到---》讓他登陸成功---》在UserToken中存一條記錄---》返回給前端json格式字串---》字串中帶一個隨機字串

  

1.1 登陸介面

# class UserView(ViewSetMixin,APIView):
class UserView(ViewSet): @action(methods=['POST'], detail=False) def login(self, request): username = request.data.get('username') password = request.data.get('password') user = User.objects.filter(username=username, password=password).first() if user:
# 登陸成功--》生成一個隨機字串-->存到token表中(如果之前有記錄,更新,如果沒有新增) # uuid生成不重複的串---》理論上不重複 token = str(uuid.uuid4()) # 偽隨機數生成,沒有引數,重複概率,比其他的高一些 UserToken.objects.update_or_create(user=user, defaults={'token': token}) # 如果存在就更新,如果不存在就新增 return Response({'code': 100, '
msg': '登陸成功', 'token': token}) else: return Response({'code': 101, 'msg': '使用者名稱或密碼錯誤'})

urls.py

#自動生成路由


from app01 import views
from rest_framework.routers import SimpleRouter
router=SimpleRouter()
router.register('user',views.UserView,'user')

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(router.urls)),
]

models.py

class User(models.Model):
    username = models.CharField(max_length=32)
    password = models.CharField(max_length=32)
    user_type = models.IntegerField(choices=((1, '超級管理員'), (2, '普通管理員'), (3, '普通使用者')))
    # gender=models.IntegerField(choices=((1,"男"),(2,"女"),(0,"未知"))) # 1:男  2:女 0:未知
    # user物件.get_欄位名_display()  快速取出gender數字對應的中文


class UserToken(models.Model):
    user = models.OneToOneField(to=User,on_delete=models.CASCADE)
    token = models.CharField(max_length=32)

1.2 認證類

# 認證類:用來校驗使用者是否登入,如果登入了,繼續往下走,如果沒有登入,直接返回
# 編寫步驟:
    -第一步:寫一個類,繼承BaseAuthentication,重寫authenticate,在方法中做校驗,校驗是否登入,返回兩個值,沒有登入拋異常
  -第二步:全域性配置,區域性配置
      -全域性配置:配置檔案中
      REST_FRAMEWORK={
      "DEFAULT_AUTHENTICATION_CLASSES":["app01.auth.LoginAuth",]
          }
    -區域性配置:在檢視類中
      class UserView(ViewSet):
        authentication_classes = [LoginAuth] 
        
    -區域性禁用:
       class UserView(ViewSet):
            authentication_classes = [] 

# 認證類中返回的兩個變數,幹啥用了
    -返回的第一個,給了request.user,就是當前登入使用者
  -返回的第二個,給了request.auth,就是token串

2 頻率

# 認證,許可權都通過以後,現在某個介面的訪問頻率---》一般根據ip或者使用者限制

# 使用步驟
    -第一步:寫一個類,繼承SimpleRateThrottle,重寫類屬性:scope,和get_cache_key方法
      get_cache_key返回什麼,就以什麼做現在,scope配置檔案中要用
    
  -第二步:在配置檔案中配置
        'DEFAULT_THROTTLE_RATES': {
        'minute_3': '3/m'  # minute_3是scope的字串,一分鐘訪問3次
        'minute_5''5/m'
    }
  -區域性使用--》檢視類中
  class BookView(GenericViewSet, ListModelMixin, RetrieveModelMixin):
    throttle_classes = [IPThrottle]
  -全域性使用--配置檔案中
     'DEFAULT_THROTTLE_CLASSES': (  # 全域性配置頻率類
        'app01.auth.IPThrottle'
    ),
  

3 許可權

# 登入成功----》所有必須登入能訪問---》每個檢視類上加認證類
# 使用者是普通使用者---》普通使用者可以訪問所有和單條
# 普通管理員和超級使用者可以操作所有,除了訪問單條和所有的那個檢視類,加上認證類
# books:檢視一條,和所有
# booksdetail路由下有:刪除,新增,修改---》許可權類加在這裡

# book 5個介面,必須登入才能訪問
# 5個介面分成了倆檢視寫:
        -BookView:獲取所有,獲取單條
      -BookDetailView:刪除,修改,新增
        -這倆檢視都需要登入:authentication_classes = [LoginAuth, ]
    -BookView只要登陸就可以操作
    -BookDetailView必須有許可權才能,加了一個許可權,permission_classes = [UserPermission, ]
    
# 跟寫認證類步驟差不多
第一步:寫一個類,繼承BasePermission,重寫has_permission,判斷如果有許可權,返回True,如果沒有許可權,返回False
第二步:區域性使用和全域性使用
    -區域性使用
    class BookDetailView(GenericViewSet, CreateModelMixin, DestroyModelMixin, UpdateModelMixin):
    permission_classes = [UserPermission, ]
    
  -全使用
      REST_FRAMEWORK={
            "DEFAULT_PERMISSION_CLASSES":["app01.auth.UserPermission",]
        }

 

autho.py

from rest_framework.permissions import BasePermission

class UserPermission(BasePermission):
    def has_permission(self, request, view):
        self.message='您是:%s,沒有許可權'%request.user.get_user_type_display()  # 沒有許可權的提示資訊
        # 如果有許可權,返回True,沒有許可權返回False
        # 許可權類,在認證類之後,request.user有了當前登入使用者
        user_type = request.user.user_type
        if user_type < 3:  # 只要不是1,2,就沒有許可權
            return True
        else:
            return False