版本,認證,權限
阿新 • • 發佈:2019-01-15
else size short 用戶表 ole onf 方案 dem 視圖
版本
DRF中版本
導入
from rest_framework.versioning import
全局配置版本控制系統
是在 URL加查詢參數
# DRF的配置 REST_FRAMEWORK = { # 配置默認使用的版本控制類 ‘DEFAULT_VERSIONING_CLASS‘: ‘rest_framework.versioning.URLPathVersioning‘, ‘DEFAULT_VERSION‘: ‘v1‘, # 默認的版本 ‘ALLOWED_VERSIONS‘: [‘v1‘, ‘v2‘], # 有效的版本 ‘VERSION_PARAM‘: ‘version‘, # 版本的參數名與URL conf中一致 }
URl
url(r‘(?P<version>[v1|v2]+)/books/$‘, views.BookListView.as_view()),
視圖:
class BookListView(ListCreateAPIView): """查看列表和創建""" queryset = models.Book.objects.all() serializer_class = BookModelSerializer # 只要配置了版本 在視圖中就能通過 request.version def get_serializer_class(self): """獲取當前序列化類的方法""" # 根據版本的不同返回不同的序列化類 print(self.request.version) if self.request.version == ‘v1‘: return BookSerializerVersion1 return self.serializer_class
局部配置
註意,通常我們是不會單獨給某個視圖設置版本控制的,如果你確實需要給單獨的視圖設置版本控制,你可以在視圖中設置versioning_class屬性,如下:
class PublisherViewSet(ModelViewSet): ... versioning_class = URLPathVersioning
認證
接下類我們就自己動手實現一個基於Token的認證方案:
自定義Token認證
表
定義一個用戶表和一個保存用戶Token的表:
class UserInfo(models.Model): name = models.CharField(max_length=32) pwd = models.CharField(max_length=32) vip = models.BooleanField(default=False) token = models.CharField(max_length=128,null=True,blank=True)
url
url(r‘users/‘,include(‘auth_demo.urls‘)), urlpatterns = [ url(r‘reg/$‘,views.RegView.as_view()), url(r‘login/$‘,views.LoginView.as_view()), url(r‘test_auth/$‘,views.TesAuthView.as_view()), ]
登錄和註冊 views
from django.shortcuts import render from rest_framework.views import APIView from auth_demo import models from rest_framework.response import Response import uuid class RegView(APIView): def post(self, request): # 獲取用戶註冊的數據 name = request.data.get(‘name‘) pwd = request.data.get(‘pwd‘) re_pwd = request.data.get(‘re_pwd‘) if name and pwd: if pwd == re_pwd: models.UserInfo.objects.create(name=name, pwd=pwd) return Response(‘註冊成功‘) else: return Response(‘兩次密碼不正確‘) else: return Response(‘無效參數‘) class LoginView(APIView): def post(self, request): name = request.data.get(‘name‘) pwd = request.data.get(‘pwd‘) if name and pwd: user_obj = models.UserInfo.objects.filter(name=name, pwd=pwd).first() if user_obj: # 生成token 保存在用戶表, 給用戶返回 token = uuid.uuid1().hex user_obj.token = token user_obj.save() return Response({‘error_on‘: 1, ‘error‘: token}) else: return Response({‘error_on‘: 1, ‘error‘: ‘用戶名或密碼錯誤‘}) else: return Response(‘無效參數‘)
局部配置認證
from auth_demo.auth import MyAuth # 登錄之後才能看到的數據接口 class TesAuthView(APIView): authentication_classes = [MyAuth, ] # 局部配置認證 def get(self, request): return Response(‘這裏只能是登陸後才能看到的地方‘)
全局配置認證 不推薦用
REST_FRAMEWORK = { ‘DEFAULT_AUTHENTICATION_CLASSES‘: [‘auth_demo.auth.MyAuth‘, ] }
自定義認證
from rest_framework.authentication import BaseAuthentication from auth_demo import models from rest_framework.exceptions import AuthenticationFailed#別人寫的拋出異常 class MyAuth(BaseAuthentication): def authenticate(self, request): #拿到頁面?後面的數據 token = request.query_params.get(‘token‘) if token: user_obj = models.UserInfo.objects.filter(token=token).first() if user_obj: # token是有效的,記住要對象和token return user_obj,token else: # 拋出異常 raise AuthenticationFailed(‘無效的token‘) else: raise AuthenticationFailed(‘請求的URL中必須攜帶token參數‘)
權限
自定義一個權限組件
‘‘‘ 自定義一個權限組件 ‘‘‘ from rest_framework.permissions import BasePermission from auth_demo import models class MyPermission(BasePermission): #提示 message = ‘這是vip才能訪問‘ def has_permission(self, request, view): # 如果你是VIP才有權限訪問 # request.user:當前經過認證的用戶對象 if request.user.vip: return True else: return False
全局配置
‘DEFAULT_PERMISSION_CLASSES‘: [‘auth_demo.permissions.MyPermission‘, ]
局部配置
from auth_demo.auth import MyAuth from auth_demo.permissions import MyPermission # 登錄之後才能看到的數據接口 class TesAuthView(APIView): authentication_classes = [MyAuth, ] # 局部配置認證 permission_classes = [MyPermission, ]#局部配置權限 def get(self, request): return Response(‘這裏只能是登陸後才能看到的地方‘)
版本,認證,權限