首页 > 编程语言 > 详细

Python+Django+rest_framework实现权限控制

时间:2020-05-19 00:32:14      阅读:99      评论:0      收藏:0      [点我收藏+]

权限控制,即对已登录的用户进行访问权限的控制。

 

1.创建表:用户表UserInfo、token表 UserToken,权限表一 CommonVideo, 权限表二 VIPVideo

from django.db import models
from datetime import datetime
# 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=32)
    password = models.CharField(max_length=64)
    add_time = models.DateTimeField(default=datetime.now, verbose_name=添加时间)
    class Meta:
        verbose_name = 用户表
        verbose_name_plural = verbose_name
    def __str__(self):
        return self.username

class UserToken(models.Model):
    """
    Token表
    """
    user = models.ForeignKey(UserInfo, on_delete=models.CASCADE)
    token = models.CharField(max_length=64)
    add_time = models.DateTimeField(default=datetime.now, verbose_name=添加时间)
    class Meta:
        verbose_name = token表
        verbose_name_plural = verbose_name
    def __str__(self):
        return self.user.username

class CommonVideo(models.Model):
    """
    普通视频
    """
    title = models.CharField(max_length=32)
    url = models.CharField(max_length=200, verbose_name=资源地址)
    add_time = models.DateTimeField(default=datetime.now, verbose_name=添加时间)
    class Meta:
        verbose_name = 普通视频表
        verbose_name_plural = verbose_name
    def __str__(self):
        return self.title


class VIPVideo(models.Model):
    """
    会员视频
    """
    title = models.CharField(max_length=32)
    url = models.CharField(max_length=200, verbose_name=资源地址)
    add_time = models.DateTimeField(default=datetime.now, verbose_name=添加时间)

    class Meta:
        verbose_name = 会员视频表
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.title

2.执行数据更新命令

python manage.py makemigration
python manage.py migrate

3.在UserInfo表中插入两条用户数据,user1 user_type=1, user2 user_type=2

4.分别在普通视频表和VIP视频表分别插入一条数据

5.安装Django REST Framework依赖

pip install djangorestframework markdown django-filter

6.settings文件添加配置

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, #新添加的配置
]

#新添加的配置
REST_FRAMEWORK = {
    DEFAULT_AUTHENTICATION_CLASSES:(
        app01.utils.auth.Authentication,
    )
}

7.在应用下,如设置的应用时app01,即在app01目录下新建一个utils目录,在该目录下新建一个auth.py文件,代码如下

from ..models import *
from rest_framework import exceptions
class Authentication(object):
    def authenticate(self, request):
        # 验证是否已经登录,函数名必须为:authenticate
        token = request._request.GET.get(token)
        token_obj = UserToken.objects.filter(token=token).first()
        print(token_obj)
        if not token_obj:
            raise exceptions.AuthenticationFailed(用户认证失败)
        # rest_framework内部会将以下元素赋值到request,以供后续使用
        return (token_obj.user, token_obj)

    def authenticate_header(self, request):
        # 这个函数可以没有内容,但是必须要有这个函数
        pass

class VIP(object):
    """
    验证VIP权限
    """

    def has_permission(self, request, view):
        if request.user.user_type < 2:
            return False
        return True

8.在app01目录下新建序列化模块文件,serializers.py,代码如下:

from rest_framework import serializers
from .models import CommonVideo, VIPVideo, SVIPVideo
class CommonVideoSerializer(serializers.ModelSerializer):
    class Meta:
        model = CommonVideo
        fields = "__all__"

class VIPVideoSerializer(serializers.ModelSerializer):
    class Meta:
        model = VIPVideo
        fields = "__all__"

class SVIPVideoSerializer(serializers.ModelSerializer):
    class Meta:
        model = SVIPVideo
        fields = "__all__"

9.编写view.py的代码

from django.shortcuts import render
from django.http import JsonResponse
from rest_framework.views import APIView
from .models import *
from .serializers import *
from rest_framework.response import Response
from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer
from rest_framework import exceptions
from .utils.auth import Authentication
from .utils.auth import VIP
# Create your views here.

def md5(user):
    import hashlib
    import time
    ctime = str(time.time())
    m = hashlib.md5(bytes(user, encoding=utf-8))
    m.update(bytes(ctime, encoding=utf-8))
    return m.hexdigest()

class AuthView(APIView):
    """
    登录
    """
    authentication_classes = []
    def post(self, request):
        ret = {code:1000, msg:登录成功!}
        try:
            user = request._request.POST.get(username)
            pwd = request._request.POST.get(password)
            obj = UserInfo.objects.filter(username=user, password=pwd).first()
            #print(user,pwd,obj)
            if not obj:
                ret[code] = 1001
                ret[msg] = 用户名或密码错误
                return JsonResponse(ret)
            #为登录用户创建token
            token = md5(user)
            #存在则更新,不存在的创建
            UserToken.objects.update_or_create(user=obj, defaults={token:token})
            ret[token] = token
        except Exception as e:
            ret[code] = 1002
            ret[msg] = 请求异常
        return JsonResponse(ret)

class Authentication(object):
    def authenticate(self, request):
        #验证是否已经登录,函数名必须为:authenticate
        token = request._request.GET.get(token)
        token_obj = UserToken.objects.filter(token=token).first()
        if not token_obj:
            raise exceptions.AuthenticationFailed(用户认证失败)
        #在rest_framework内部会将以下两个元素赋值到request,以供后续使用
        return (token_obj.user, token_obj)
    def authenticate_header(self, request):
        #这个函数可以没有内容,但是必须要有这个函数
        pass

class CommonVideoView(APIView):
    """
    登录后即可访问的内容资源
    """
    renderer_classes = [JSONRenderer]
    #渲染器
    authentication_classes = [Authentication,]
    def get(self, request):
        video_list = CommonVideo.objects.all()
        re = CommonVideoSerializer(video_list, many=True)
        return Response(re.data)

class VIPVideoView(APIView):
    """
    VIP可访问的资源
    """
    renderer_classes = [JSONRenderer]
    #渲染器
    permission_classes = [VIP,]
    def get(self, request):
        video_list = VIPVideo.objects.all()
        re = VIPVideoSerializer(video_list, many=True)
        print("***",video_list, re)
        return Response(re.data)

10.urls.py文件中添加路由

from django.contrib import admin
from django.urls import path
from app01.views import AuthView, CommonVideoView, VIPVideoView
urlpatterns = [
    path(admin/, admin.site.urls),
    path(auth/, AuthView.as_view(), name = auth),
    path(common/, CommonVideoView.as_view(), name=common),
    path(vip/, VIPVideoView.as_view(), name=vip),
]

验证

1.使用postman,post请求登录user1

2.登录成功,使用登录成功返回的token访问common,返回commonVideo表数据信息,访问vip,提示无权限

3.使用postman,post请求登录user2

4.登录成功,使用登录成功返回的token访问common,返回commonVideo表数据信息,访问vip,返回VIPVideo表数据信息

Python+Django+rest_framework实现权限控制

原文:https://www.cnblogs.com/dayan007/p/12914008.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!