69、权限控制 、django中做权限控制 、开发中做权限控制 、基于django的auth+admin+第三方快速开发 、 django-vue-admin

455 阅读7分钟

权限控制

ACL-访问控制列表

1.ACL(访问控制列表)的权限控制:(针对互联网用户的产品)
	用户表:
		"""
	  id    name      password
    1     zhangsan   123
		"""
    
	权限表:
    """
      id   user_id    权限
      1     1         评论权限
      2     1         发抖音权限
    """
	张三:[评论权限,发抖音权限]

RBAC-基于角色的访问控制

1.RBAC(Role-Based Access Control)基于角色的访问控制:(针对于公司内部项目)
权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。这样管理都是层级相互依赖的,权限赋予给角色,而把角色又赋予用户,这样的权限设计很清楚,管理起来很方便

2.应用
	Django的 Auth组件 采用的认证规则就是RBAC
		1.像专门做人员权限管理的系统(CRM系统)都是公司内部使用,所以数据量都在10w一下,一般效率要求也不是很高
		2.用户量极大的常规项目,会分两种用户:前台用户(三大认证) 和 后台用户(BRAC来管理)
		结论:没有特殊要求的Django项目可以直接采用Auth组件的权限六表,不需要自定义六个表,也不需要断开表关系,单表可能需要自定义User表

3.前后台权限控制
	1.后台用户对各表操作,是后台项目完成的,我们可以直接借助admin后台项目(Django自带的)
	2.后期也可以用xadmin框架来做后台用户权限管理

	3.前台用户的权限管理如何处理
		定义了一堆数据接口的视图类,不同的登录用户是否能访问这些视图类,能就代表有权限,不能就代表无权限
		前台用户权限用drf框架的 三大认证

django中的的auth

1.django的auth其实就实现了基于角色的访问控制--->通过表控制的(6张)
		1.auth_user :用户表,存用户信息
		2.auth_group:组,角色,存放角色信息
		3.auth_permission:权限,存放权限信息
    # 分析:一个组(角色)中,有多个用户,一个用户,属于多种角色---->多对多
		4.auth_user_groups:用户和组的多对多中间表
    # 分析:一个组,可能有多个权限,一个权限,也可能属于多个组--->多对多
		5.auth_group_permissions:组和权限的多对多中间件
    
    # django,多了张表:auth_user_user_permissions
    # 分析:一个用户,可以有多个权限,一个权限,可以分配个多个用户--->多对多
		6.auth_user_user_permissions:用户和权限多对多中间表

django中,如何做权限控制

1.创建书籍表,用户表
  class User(models.Model):
      username = models.CharField(max_length=32)
      password = models.CharField(max_length=64)
      age  = models.IntegerField()
      email = models.CharField(max_length=64)
      class Meta:
          verbose_name_plural = '用户表'
          
    class Book(models.Model):
        name = models.CharField(max_length=32)
        price = models.CharField(max_length=64)
        class Meta:
            verbose_name_plural = '书籍表'
        def __str__(self):
            return self.name
          
2.在管理员中注册
	from django.contrib import admin
  from .models import Book
	admin.site.register(Book)
  
3.通过登陆django自己提供的后台管理系统,对书籍用户进行增删改,使得不同的用户,可以拥有不同的角色和权限

开发中做权限控制

1.基于python开发,公司内部项目用的多-->使用基于角色的访问控制的权限比较多
2.python+django 开发出一套公司内部项目,要带rbac的权限控制
	1.基于django的auth+admin快速开发,有更多操作,但是没学
	2.基于django的auth+admin+第三方美化快速开发
    	国内的:simple-ui,xadmin(弃用了)
	3.基于django+vue+自定制权限 
			djagno-vue-admin :第三方开源
	4.完全自己写

基于django的auth+admin+第三方美化快速开发

准备

1.安装:pip3 install django-simpleui
2.将simpleui注册--修改默认后台模板为simpleui
      INSTALLED_APPS = [
        'simpleui',
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app01.apps.App01Config',
        'rest_framework'
    ]
  
详细教程:https://simpleui.72wo.com/docs/simpleui/quick.html#%E7%9B%AE%E5%BD%95

主题

1.默认主题:默认主题在settings.py中进行配置
    # 指定simpleui默认的主题,指定一个文件名,相对路径就从simpleui的theme目录读取
    SIMPLEUI_DEFAULT_THEME = 'admin.lte.css'
    
2.也可以在后台选择主题

图标

1.simpleui中显示的图标,可以在https://fontawesome.com/icons?d=gallery中查找

2.默认图标:simpleui对所有菜单提供了一个默认的file图标,是为了统一风格。也许你并不喜欢,你可以选择关闭默认图标
	SIMPLEUI_DEFAULT_ICON = False   # 关闭默认图标
  
3.自定义图标:simpleui仅为系统默认模块提供了图标,如果要为其他模块指定图标,可以自定义配置。图标参考请查阅:图标说明		优先级: 自定义->系统配图->默认图标
    key:模块名字,请注意不是model的命名,而是菜单栏上显示的文本,因为model是可以重复的,会导致无法区分
    vlaue	图标
    
    eg:
    SIMPLEUI_ICON = {
    '系统管理': 'fab fa-apple',
    '员工管理': 'fas fa-user-tie'
		}
        

菜单

1.name:菜单名
2.icon:图标,参考element-ui和fontawesome图标
3.url:链接地址,绝对或者相对,如果存在models字段,将忽略url
4.models:子菜单,自2021.02.01+版本 支持最多3级菜单,使用方法可以看下方例子
5.newTab:boolean,default:False,浏览器新标签中打开,自2022.6.13开始支持
import time

SIMPLEUI_CONFIG = {
    'system_keep': False,
    'menu_display': ['我的地盘', '权限认证', '多级菜单测试', '动态菜单测试', '图书管理'],  # 开启排序和过滤功能, 不填此字段为默认排序和全部显示, 空列表[] 为全部不显示.
    'dynamic': True,  # 设置是否开启动态菜单, 默认为False. 如果开启, 则会在每次用户登陆时动态展示菜单内容
    'menus': [
        {
            'name': '我的地盘',
            'icon': 'fas fa-code',
            'url': '/https://gitee.com/tompeppa/simpleui/',
            # 浏览器新标签中打开
            # 'newTab': True,
        },
        {
            'app': 'auth',
            'name': '权限认证',
            'icon': 'fas fa-user-shield',
            'models': [{
                'name': '用户',
                'icon': 'fa fa-user',
                'url': 'auth/user/'
            }]
        },
        {
            # 自2021.02.01+ 支持多级菜单,models 为子菜单名
            'name': '多级菜单测试',
            'icon': 'fa fa-file',
            # 二级菜单
            'models': [
                {
                    'name': 'Baidu',
                    'icon': 'far fa-surprise',
                    # 第三级菜单 ,
                    'models': [
                        {
                            'name': '爱奇艺',
                            'url': 'https://www.iqiyi.com/dianshiju/'
                            # 第四级就不支持了,element只支持了3级
                        },
                        {
                            'name': '百度问答',
                            'icon': 'far fa-surprise',
                            'url': 'https://zhidao.baidu.com/'
                        }
                    ]
                },
                {
                    'name': '内网穿透',
                    'url': 'https://www.wezoz.com',
                    'icon': 'fab fa-github'
                }]
        },
        {
            'name': '动态菜单测试',
            'icon': 'fa fa-desktop',
            'models': [{
                'name': time.time(),
                'url': 'http://baidu.com',
                'icon': 'far fa-surprise'
            }]
        },
        {
            'app': 'app01',
            'name': '图书管理',
            'icon': 'fas fa-user-shield',
            'models': [
                {
                    'name': '书本管理',
                    'icon': 'fa fa-user',
                    'url': 'app01/book/'
                },
                {
                    'name': '出版社管理',
                    'icon': 'fa fa-user',
                    'url': 'app01/publish/'
                },
            ]
        },

    ]
}

自定义按钮&Action

1.django admin 默认提供了自定义按钮的支持,但是样式、图标均不可自定义,simpleui在django admin 自定义action的基础上增加了样式、图标、按钮类型自定义。

@admin.register(Book)
class EmployeAdmin(admin.ModelAdmin):
    list_display = ('id', 'name', 'price')  # 列表页面,展示的字段

    # 增加自定义按钮
    actions = [ 'custom_button']

    def custom_button(self, request, queryset):
        print(request)
        print(queryset)

    # 显示的文本,与django admin一致
    custom_button.short_description = '测试按钮'
    # icon,参考element-ui icon与https://fontawesome.com
    custom_button.icon = 'fas fa-audio-description'

    # 指定element-ui的按钮类型,参考https://element.eleme.cn/#/zh-CN/component/button
    custom_button.type = 'success'

    # 给按钮追加自定义的颜色
    custom_button.style = 'color:black;'

    def make_copy(self, request, queryset):
        pass
    make_copy.short_description = '复制员工'
还有:其他相关配置

djagno-vue-admin演示

https://gitee.com/liqianglog/django-vue-admin

作业

1.多方式登录接口
	使用auth的user表扩写
	用户名+密码
	手机号+密码
	邮箱+密码 
	签发token逻辑,放在序列化类中写

views.py

from rest_framework.viewsets import ViewSet
from .serializer import UserSerializer
from rest_framework.response import Response

class LoginView(ViewSet):

    def login(self,request):
        # 获取用户名/手机号/邮箱   密码
        ser = UserSerializer(data = request.data)
        if ser.is_valid():
            print(ser)
            token =ser.save_user(ser.validated_data)
            return Response({'code':100,'msg':'登陆成功','token':token})
        else:
            return Response({'code': 101, 'msg': '登陆失败', 'erros':ser.errors})

serializer.py

from .models import User
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from rest_framework_jwt.settings import api_settings
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['info','password']

    info = serializers.CharField()

    def _generate_token(self,user):
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        print(token)
        return token



    def validate(self, attrs):
        username =None
        email = None
        phone = None
        user_info = attrs.get('info')
        password = attrs.get('password')
        # 手机号 用户名 邮箱
        if user_info.isdigit():
            phone = attrs.get('info')
            print(phone)
        elif '@'in user_info:
            email = attrs.get('info')
            print(email)
        else:
            username = attrs.get('info')
            print(username)
        # 查找用户

        if phone:
            user = User.objects.filter(phone=phone,password=password).first()
        if email:
            user = User.objects.filter(email=email,password=password).first()
        if username:
            user = User.objects.filter(username=username,password=password).first()
        if not user:
            raise ValidationError('用户不存在')
        attrs['user'] = user
        return attrs

    def save_user(self, validated_data):
        user = validated_data['user']
        token = self._generate_token(user)
        return token