• django-权限管理


     

    django-权限管理

    第一步

    #创建表
    
    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=64)
        is_menu = models.BooleanField(verbose_name="是否是菜单")
        class Meta:
            verbose_name_plural = "权限表"               #添加表到后台中去
    
        def __str__(self):
            return self.title
    
    class User(models.Model):
        """
        用户表
        """
        username = models.CharField(verbose_name='用户名',max_length=32)         #verbose_name将在后台页面上显示自定义的名字
        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)
        class Meta:
            verbose_name_plural = "用户表"                            #添加用户表到后台中去
    
        def __str__(self):
            return self.username
    
    class Role(models.Model):
        """
        角色表
        """
        title = models.CharField(max_length=32)
        permissions = models.ManyToManyField(verbose_name='具有的所有权限',to='Permission',blank=True)    #blank=True的作用是关联的角色可以为空
        class Meta:
            verbose_name_plural = "角色表"                         #添加角色表到后台中去
    
        def __str__(self):
            return self.title
    
    
    
    
    
    
    
    第二步
    根据django自己的admin来登陆
    from django.conf.urls import url
    from django.contrib import admin
    from rbac import views
    from app01 import views as app01_views
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
    ]
    在项目目录里创建登陆用户名和密码
     
    #创建用户名和密码
    python manage.py createsuperuser      
    
     然后进行登陆输入你自己创建的用户名和密码
     登陆进去,那么怎么显示你的表呢
    #在admin.py里导入
            from django.contrib import admin
            from . import models             
            admin.site.register(models.Permission)                           
            admin.site.register(models.User)
            admin.site.register(models.Role)
     运行结果
     可以看到默认是数据库的表名一一对应的,还可以更改名字
     class Role(models.Model):
        """
        角色表
        """
        title = models.CharField(max_length=32)
        permissions = models.ManyToManyField(verbose_name='具有的所有权限',to='Permission',blank=True)
        class Meta:
            verbose_name_plural = "角色表"
    
        def __str__(self):
            return self.title
       
        class Meta:                                           #添加 Meta
            verbose_name_plural = "角色表"                    #更改名字
    输出结果:
     
    第三步
    用户登录程序
        - 获取当前用户具有的所有权限(去重)
         - 获取权限中的url,放置到session中
    初始化权限信息,获取权限信息并放置到session中
    import re
    
    from django.shortcuts import render,redirect,HttpResponse
    from rbac import models
    from rbac.service.init_permission import init_permission                             #导入自己写的初始化的模块
    def login(request):
        if request.method == "GET":
            return render(request,'login.html')
        else:
            user = request.POST.get('user')
            pwd = request.POST.get('pwd')
            user = models.User.objects.filter(username=user,password=pwd).first()          #首先先查到用户输入的user字段存不存在找到用户输入的字段
            print(request.POST)                
            if not user:                                                                     #判断用户在不在
                return render(request, 'login.html')                                          #如果不在则返回login页面
            init_permission(user,request)                                                     #把user的对象和接收的用户信息传过去
            return redirect('/index/')                       
    
    
    def index(request):
    
        return HttpResponse('欢迎登录')
    
    
    def userinfo(request):
        return HttpResponse('用户列表页面')
    
    
    def userinfo_add(request):
        return HttpResponse('添加用户页面')
    
    def order(request):
        return HttpResponse('订单列表页面')
    
    def order_add(request):
        return HttpResponse('添加订单页面')
    def init_permission(user,request):                                           #这里接受了视图函数传过来的user querset对象和request用户的信息
        """
        初始化权限信息,获取权限信息并放置到session中。
        :param user:
        :param request:
        :return:
        """
        permission_list = user.roles.values('permissions__title', 'permissions__url', 'permissions__is_menu').distinct()            #   通过user的对象正向查询向下滑线查询拿到title,url,is_menu字段并进行去重
        url_list = []                                                                                                            #定义一个空字典
        for item in permission_list:                                                                                   #循环permission_list所有的值
            url_list.append(item['permissions__url'])                                                                  #把url的字段的内容放入定义的空字典中
        print(url_list)                         
        request.session['permission_url_list'] = url_list                                                              #通过这里通过了说明这个用户名是存在的把所有的url字段权限的信息加入到session中
    
     
    第四步 
    在通过中间件来进行权限的管理
    想要进行权限控制需要login和后台的admin路径对外开放,然后用户能够通过登陆来进行权限的验证,不然就会陷入死循环
    白名单:
    #自定制的
    # ######################### rbac ############################
    #白名单
    VALID_URL = [
        "/login/",
        "/admin.*"
    ]
     



    import re
    
    from django.shortcuts import redirect,HttpResponse
    from django.conf import settings                                                #settings是django特有的 在settings中都可以通过django.conf来调用,
    
    class MiddlewareMixin(object):
        def __init__(self, get_response=None):
            self.get_response = get_response
            super(MiddlewareMixin, self).__init__()
    
        def __call__(self, request):
            response = None
            if hasattr(self, 'process_request'):
                response = self.process_request(request)
            if not response:
                response = self.get_response(request)
            if hasattr(self, 'process_response'):
                response = self.process_response(request, response)
            return response
    
    
    class RbacMiddleware(MiddlewareMixin):
    
        def process_request(self,request):                      
            # 1. 获取当前请求的URL
            # request.path_info
            # 2. 获取Session中保存当前用户的权限
            # request.session.get("permission_url_list')
            current_url = request.path_info                             #获取到用户输入的Url地址
    
            # 当前请求不需要执行权限验证
            for url in settings.VALID_URL:                             #拿到白名单 进行for循环验证因为白名单是一个列表的形式如果用户输入的url存在于白名单之中的
                if re.match(url,current_url):                          #用循环取出的白名单与用户输入的url路径进行re正则判断,判断成功则有值,没有成功则没有值
                    return None                                        #成功return None 则继续运行后面的中间件和视图函数
    
            permission_list = request.session.get("permission_url_list")       #通过request,get session中的值,如果没有则为空
            if not permission_list:                                           #进行判断
                return redirect('/login/')                                    #没有的话则重定向login登陆页面中
               #如果有的话则继续执行下面代码
            flag = False                                                     
            for db_url in permission_list:                               #有值则循环取值
                regax = "^{0}$".format(db_url)                           #把循环的值通过.format按索引值穿参进行字符串拼接    注:如果不进行字符串的拼接加上^$的话,匹配的值只要一个正确后面的就不管了,比如addteacher/   addteacher/add/1这样的也能匹配成功,所以通过^$以..开头和以..结尾能够进行精确的匹配   
                if re.match(regax, current_url):                          #进行re正则匹配这样就能精确的匹配了,
                    flag = True                                           #正则匹配成功的话flag=True
                    break                                                 #匹配成功了直接就退出循环了
    
            if not flag:                                                  #用户的权限不匹配的话,则进行not false 就是true表示成功则往下执行
                return HttpResponse('无权访问')                            #直接返回无权访问
    
    权限管理流程图
     

































  • 相关阅读:
    学习笔记 Nim
    学习笔记 Multi-Nim
    学习笔记 Anti-Nim
    机器学习 2
    机器学习 1
    2020 ICPC 南京 by chinakevin @CraZyMoon 狂月
    浙江省赛 2020 (ZJCPC2020)(The 17th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple)
    Selection Contest for Rookies 4 E Polycarp's New Job
    AtCoder Beginner Contest 166 F Three Variables Game
    Codeforces Round #638 (Div. 2) E Phoenix and Berries
  • 原文地址:https://www.cnblogs.com/zcfx/p/7895348.html
Copyright © 2020-2023  润新知