zoukankan      html  css  js  c++  java
  • RBAC 继完善代码之后的,再一次完善

    在上一篇文章中,我的中间件是 保存在我的web 业务app 中的。
    但是rbac我想要完成的是一个 组件的功能, 所以这个验证的 中间件,  何不放到rbac的app之中:

    为了太乱先放一个项目的目录图片:


    不要忘记我们的目的: 做一个 可以灵活使用的rbac 权限组件:
    先看看setting中的配置:

    import os
    
    # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    
    
    # Quick-start development settings - unsuitable for production
    # See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/
    
    # SECURITY WARNING: keep the secret key used in production secret!
    SECRET_KEY = 'o+ym86530)hs=+26$$n=+l(w$belc-3uu0aa%9+*(snlac-5@a'
    
    # SECURITY WARNING: don't run with debug turned on in production!
    DEBUG = True
    
    ALLOWED_HOSTS = []
    
    
    # Application definition
    
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'rbac.apps.RbacConfig',
        'web.apps.WebConfig',
    ]
    
    # 编写中间件,对用户权限,进行校验
    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',
        "rbac.middlewares.rbac.RbacMiddleware",
    ]
    
    ROOT_URLCONF = 'crm_learn.urls'
    
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates')]
            ,
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]
    
    WSGI_APPLICATION = 'crm_learn.wsgi.application'
    
    
    # Database
    # https://docs.djangoproject.com/en/2.1/ref/settings/#databases
    
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        }
    }
    
    
    # Password validatiALLOWED_HOSTSon
    # https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators
    
    AUTH_PASSWORD_VALIDATORS = [
        {
            'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
        },
    ]
    
    
    # Internationalization
    # https://docs.djangoproject.com/en/2.1/topics/i18n/
    
    LANGUAGE_CODE = 'en-us'
    
    TIME_ZONE = 'UTC'
    
    USE_I18N = True
    
    USE_L10N = True
    
    USE_TZ = True
    
    
    # Static files (CSS, JavaScript, Images)
    # https://docs.djangoproject.com/en/2.1/howto/static-files/
    
    STATIC_URL = '/static/'
    
    
    # ################## 默认文件上传配置 ########################
    from django.core.files.uploadhandler import MemoryFileUploadHandler
    from django.core.files.uploadhandler import TemporaryFileUploadHandler
    
    # List of upload handler classes to be applied in order.
    FILE_UPLOAD_HANDLERS = [
        'django.core.files.uploadhandler.MemoryFileUploadHandler',
        'django.core.files.uploadhandler.TemporaryFileUploadHandler',
    ]
    
    # Maximum size, in bytes, of a request before it will be streamed to the
    # file system instead of into memory.
    # 允许内存中上传文件的大小
    #   合法:InMemoryUploadedFile对象(写在内存)         -> 上传文件小于等于 FILE_UPLOAD_MAX_MEMORY_SIZE
    # 不合法:TemporaryUploadedFile对象(写在临时文件)     -> 上传文件大于    FILE_UPLOAD_MAX_MEMORY_SIZE 且 小于 DATA_UPLOAD_MAX_MEMORY_SIZE
    
    FILE_UPLOAD_MAX_MEMORY_SIZE = 2621440  # i.e. 2.5 MB
    
    # Maximum size in bytes of request data (excluding file uploads) that will be
    # read before a SuspiciousOperation (RequestDataTooBig) is raised.
    # 允许上传内容的大小(包含文件和其他请求内容)
    DATA_UPLOAD_MAX_MEMORY_SIZE = 2621440  # i.e. 2.5 MB
    
    # Maximum number of GET/POST parameters that will be read before a
    # SuspiciousOperation (TooManyFieldsSent) is raised.
    # 允许的上传文件数
    DATA_UPLOAD_MAX_NUMBER_FIELDS = 1000
    
    # Directory in which upload streamed files will be temporarily saved. A value of
    # `None` will make Django use the operating system's default temporary directory
    # (i.e. "/tmp" on *nix systems).
    # 临时文件夹路径
    FILE_UPLOAD_TEMP_DIR = None
    
    # The numeric mode to set newly-uploaded files to. The value should be a mode
    # you'd pass directly to os.chmod; see https://docs.python.org/3/library/os.html#files-and-directories.
    # 文件权限
    FILE_UPLOAD_PERMISSIONS = None
    
    # The numeric mode to assign to newly-created directories, when uploading files.
    # The value should be a mode as you'd pass to os.chmod;
    # see https://docs.python.org/3/library/os.html#files-and-directories.
    # 文件夹权限
    FILE_UPLOAD_DIRECTORY_PERMISSIONS = None
    
    # session-key配置
    PERMISSIONS_SESSION_KEY = "permissions__url"
    
    # 配置权限 白名单
    VALID_URL_LIST = ["/login/", "/admin/"]
    
    
    LOGGING = {
        'version': 1,
        'disable_existing_loggers': False,
        'handlers': {
            'console':{
                'level':'DEBUG',
                'class':'logging.StreamHandler',
            },
        },
        'loggers': {
            'django.db.backends': {
                'handlers': ['console'],
                'propagate': True,
                'level':'DEBUG',
            },
        }
    }
    settiongs

    我在配置文件中 添加的这两个, 配置项。

    # session-key配置   为了解决以后我可能想要更换 session-key的 问题
    PERMISSIONS_SESSION_KEY = "permissions__url"

    # 配置权限 白名单  为了一些我并不想 通过rbac组件进行权限验证的一些白名单
    VALID_URL_LIST = ["/login/", "/admin/"]

    然后是 权限认证的中间件:

    通过引入settings 的到, session-key 和 白名单。 在中间件进行验证

    rom django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import HttpResponse
    from django.conf import settings
    import re
    
    
    class RbacMiddleware(MiddlewareMixin):
        '''用户权限信息的校验'''
        def process_request(self, request):
            '''当用户请求进入时 触发执行'''
            '''
            1. 获取当前用户请求的url
            2. 获取当前用户在session中保存的 权限列表 [......]
            3. 当前请求url 在 session中, 就可以,进行访问
            '''
            current_url = request.path_info
            for valid_url in settings.VALID_URL_LIST:
                if re.match(valid_url, current_url):  # 先一步进行白名单的验证
                    return None 
            permission_list = request.session.get(settings.PERMISSIONS_SESSION_KEY)
    
            if not permission_list:
                return HttpResponse("您没有访问权限...请联系管理员")
            flag = False
            for url in permission_list:
                reg = "^%s$" % url 
                if re.match(reg, current_url):
                    flag = True
                    break
            if not flag:
                return HttpResponse("无权访问")
    rbac.middlewares.rbac.RbacMiddleware

    然后是modles:

    from django.db import models
    
    
    class Permission(models.Model):
        """
        权限表
        """
        title = models.CharField(verbose_name='标题', max_length=32)
        url = models.CharField(verbose_name='含正则的URL', max_length=128)
    
        def __str__(self):
            return self.title
    
    
    class Role(models.Model):
        """角色"""
        title = models.CharField(verbose_name='角色名称', max_length=32)
        permissions = models.ManyToManyField(verbose_name='拥有的所有权限', to='Permission', blank=True)
    
        def __str__(self):
            return self.title
    
    
    class UserInfo(models.Model):
        """
        用户表
        """
        name = models.CharField(verbose_name='用户名', max_length=32)
        password = models.CharField(verbose_name='密码', max_length=64)
        email = models.CharField(verbose_name='邮箱', max_length=32)
        roles = models.ManyToManyField(verbose_name='拥有的所有角色', to='Role', blank=True)
    
        def __str__(self):
            return self.name
    rbac.models

     然后是 web 业务的视图函数中:

    在这里我们直接引入rbac组件中 service.init_permission  权限初始化函数 init_permission(current_user, request)
    来进行,权限的初始化。 并且跳转到 主页面。

    from django.shortcuts import HttpResponse, redirect, render
    from rbac.models import *
    from rbac.service.init_permission import init_permission
    
    
    def login(request):
        if request.method == "POST":
            user = request.POST.get("user")
            pwd = request.POST.get("pwd")
    
            current_user = UserInfo.objects.filter(name=user, password=pwd).first()
    
            if not current_user:
                return render(request, "login.html", {"msg": "username or password is wrong"})
    
            init_permission(current_user, request)
            return redirect("/customer/list/")
        return render(request, "login.html", locals())
    web.views.account
  • 相关阅读:
    《ML模型超参数调节:网格搜索、随机搜索与贝叶斯优化》
    《黎曼几何与流形学习》
    《信息几何优化,随机优化, 与进化策略》
    生产订单加反作废按钮
    生产订单新增按钮没权限
    生产订单备注字段锁定
    审核后提交物料附件
    MRP设置自动执行
    CRM系统数据授权
    复制物料时不复制安全库存
  • 原文地址:https://www.cnblogs.com/chengege/p/10696476.html
Copyright © 2011-2022 走看看