1. 程式人生 > >版本,認證,權限

版本,認證,權限

else size short 用戶表 ole onf 方案 dem 視圖

            版本

DRF中版本

導入

from rest_framework.versioning import

  

技術分享圖片

全局配置版本控制系統 

/v1/books/ 是在 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

/books/?version=v1

技術分享圖片

局部配置

註意,通常我們是不會單獨給某個視圖設置版本控制的,如果你確實需要給單獨的視圖設置版本控制,你可以在視圖中設置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(‘這裏只能是登陸後才能看到的地方‘)

版本,認證,權限