DRF权限组件

1.DRF权限组件(局部+全局) 

  和上述的认证组件使用方式一样,定义一个权限类,必须要有def has_permission(self,request, view):pass方法,可以在类中定义变量message指定无权限时的提示内容。

  权限组件也可以在视图中局部使用,或者在settings.py中进行全局配置

  在有注册登录操作时,为了避免认证和权限,还是继承View最好或使用局部认证配置。

   

 

 

 

  settings.py  

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01.apps.App01Config',
    'rest_framework',
]
 
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
 
REST_FRAMEWORK = {
    #认证配置(全局配置)----针对所有的继承APIView的类,最终都会有结果返回
    'DEFAULT_AUTHENTICATION_CLASSES' : ['app01.utils.auth.MyAuth',],#可以自定义多个认证类
    # 'UNAUTHENTICATED_USER':lambda :'匿名用户request.user自定义值',#request.user有默认值
    # 'UNAUTHENTICATED_TOKEN':lambda :'request.auth自定义值',#request.auth有默认值
 
    #权限配置(全局配置)----针对-针对所有的继承APIView的类,在认证之后执行,没有权限会返回message,有权限继续执行
    'DEFAULT_PERMISSION_CLASSES':['app01.utils.permission.SVIPPermission',]#可以自定义多个权限
 
}
settings.py

  utils--auth.py--MyAuth认证类  

#认证组件
from rest_framework.authentication import BaseAuthentication,BasicAuthentication
 
class MyAuth(BaseAuthentication):#可以直接继承BaseAuthentication类,可以省略authenticate_header方法,或者继承BasicAuthentication
    def authenticate(self, request):
                token = request._request.GET.get('token')
        token_obj = models.UserToken.objects.get(token=token)
        if not token_obj:
            raise exceptions.AuthenticationFailed('未认证用户!!!')
        return (token_obj.user', 'request.auth')  # 认证函数执行结果如果通过则为元组,元组第一个元素封装在为request.user
utils--auth.py--MyAuth认证类 

  utils--permission.py--SVIPPermission/MyPermission权限类

# 权限组件
class SVIPPermission(object):
    # message = 'You do not have permission to perform this action.'#默认值
    message = '无此权限!!!'
    def has_permission(self,request, view):
        if request.user.user_type == 3:
            return False    #False为没权限
        return True   #True为有权限
 
 
class MyPermission(object):
    def has_permission(self,request, view):
        if request.user.user_type != 3:
            return False
        return True
utils--permission.py--SVIPPermission/MyPermission权限类

  models.py

from django.db import models
# Create your models here
class UserInfo(models.Model):
    """
    用户表
    """
    user_type_choices = [
        (1, '普通用户'),
        (2, 'VIP用户'),
        (3, 'SVIP用户'),
    ]
    user_type = models.IntegerField(choices=user_type_choices)
    username = models.CharField(max_length=10, unique=True)
    password = models.CharField(max_length=12, null=False)
 
 
class UserToken(models.Model):
    """
    token表
    """
 
    user = models.OneToOneField(to='UserInfo')
    token = models.CharField(max_length=64)
    create_time = models.DateTimeField(auto_now=True)
 
 
class Book(models.Model):
    name = models.CharField(max_length=12)
models.py

  urls.py

from django.conf.urls import url
from django.contrib import admin
from app01 import views
 
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^api/v1/login/$', views.AuthView.as_view()),
    url(r'^book/$', views.BookView.as_view(),name='book'),
    url(r'^order/$', views.OrderView.as_view(),name='order'),
 
]
urls.py

  views.py

 
from django.shortcuts import render, HttpResponse
from rest_framework.views import APIView
from app01 import models
from django.http import JsonResponse
from app01.utils.auth import MyAuth
from app01.utils.permission import MyPermission,SVIPPermission
from django.views import View
 
# Create your views here.
 
# 实例url:http://127.0.0.1:8000/book/?token=1
class BookView(APIView):
    # # (1)认证组件(局部使用)
    # authentication_classes = [MyAuth, ]
    #(2)权限组件(局部使用)---局部和全局都有时从局部优先
    permission_classes = [MyPermission,]
 
 
    def get(self, request):
        print(request.user)  #request.user在APIViewD的dispatch中进行封装的
        return HttpResponse('GET')
 
    def post(self, request):
        return HttpResponse('POST')
 
    def put(self, request):
        return HttpResponse('PUT')
 
    def patch(self, request):
        return HttpResponse('PATCH')
 
    def delete(self, request):
        return HttpResponse('DELETE')
 
 
class OrderView(APIView):
    # (1)认证组件
    authentication_classes = [MyAuth, ]
    # (2)权限组件
    # permission_classes = [SVIPPermission]
 
    def get(self, request):
        print(request.user)  # request.user在认证组件中进行封装的
        return HttpResponse('GET')
 
    def post(self, request):
        return HttpResponse('POST')
 
    def put(self, request):
        return HttpResponse('PUT')
 
    def patch(self, request):
        return HttpResponse('PATCH')
 
    def delete(self, request):
        return HttpResponse('DELETE')
 
 
import time
import hashlib
 
 
def token_md5(username):
    """
    自定义token
    :param username:
    :return:
    """
    t = time.time()
    md5 = hashlib.md5(str(t).encode('utf-8'))
    md5.update(username.encode('utf-8'))
    return md5.hexdigest()
 
 
class AuthView(View):
    #如果不注册自定义组件,走默认的认证,最后返回了request.user和request.auth都是匿名用户默认值,可以在settings.py中加载自定义配置
    #但是在权限认证是不好通过,所以还是直接继承View
    def post(self, request):
        """
        用户登录
        :param request:进行封装之后的request对象
        :return: 登录结果信息
        """
        ret = {'code': 0, 'msg': ''}
 
        username = request.POST.get('username', None)
        password = request.POST.get('password', None)
 
        # 每次登陆如果有就更新没有就创建
        try:
            user_obj = models.UserInfo.objects.filter(username=username, password=password).first()
            if user_obj:
                token = token_md5(username)
                print(token)
                # 每次登陆如果有就更新没有就创建
                models.UserToken.objects.update_or_create(user=user_obj, defaults={'token': token})
                ret['msg'] = '登陆成功!'
                ret['token'] = token
            else:
                ret['code'] = 1
                ret['msg'] = '账号或密码有误!!!'
 
        except Exception as e:
            ret['code'] = 2
            ret['msg'] = '未知错误!!!'
        finally:
            return JsonResponse(ret)
views.py

 

2. DRF权限组件继承类(全局)  

  在自定义权限组件类时,推荐继承BasePermission类,重写def has_permission(self,request, view):pass方法

  

 

   

utils--permission.py--SVIPPermission/MyPermission权限类  

from rest_framework.permissions import BasePermission
 
# 权限组件
class SVIPPermission(BasePermission):#推荐继承BasePermission类
    # message = 'You do not have permission to perform this action.'#默认值
    message = '无此权限!!!'
    def has_permission(self,request, view):
        if request.user.user_type == 3:
            return False    #False为没权限
        return True   #True为有权限
 
class MyPermission(BasePermission):#推荐继承BasePermission类
    def has_permission(self,request, view):
        if request.user.user_type != 3:
            return False
        return True
utils--permission.py--SVIPPermission/MyPermission权限类

settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01.apps.App01Config',
    'rest_framework',
]
 
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
 
REST_FRAMEWORK = {
    #认证配置(全局配置)----针对所有的继承APIView的类,最终都会有结果返回
    'DEFAULT_AUTHENTICATION_CLASSES' : ['app01.utils.auth.MyAuth',],#可以自定义多个认证类
    # 'UNAUTHENTICATED_USER':lambda :'匿名用户request.user自定义值',#request.user有默认值
    # 'UNAUTHENTICATED_TOKEN':lambda :'request.auth自定义值',#request.auth有默认值
 
    #权限配置(全局配置)----针对-针对所有的继承APIView的类,在认证之后执行,没有权限会返回message,有权限继续执行
    'DEFAULT_PERMISSION_CLASSES':['app01.utils.permission.SVIPPermission',]#可以自定义多个权限
 
}
settings.py

 

posted @ 2019-09-23 16:39  笑得好美  阅读(701)  评论(0编辑  收藏  举报