zoukankan      html  css  js  c++  java
  • 权限管理具体代码实现

    1、settings

      1 """
      2 Django settings for day80 project.
      3 
      4 Generated by 'django-admin startproject' using Django 1.11.6.
      5 
      6 For more information on this file, see
      7 https://docs.djangoproject.com/en/1.11/topics/settings/
      8 
      9 For the full list of settings and their values, see
     10 https://docs.djangoproject.com/en/1.11/ref/settings/
     11 """
     12 
     13 import os
     14 
     15 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
     16 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
     17 
     18 
     19 # Quick-start development settings - unsuitable for production
     20 # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
     21 
     22 # SECURITY WARNING: keep the secret key used in production secret!
     23 SECRET_KEY = '7x(f$0j0c#)hn)8i(uv6j*sg^h_7v9$eak#pu_n4ji05=v28ca'
     24 
     25 # SECURITY WARNING: don't run with debug turned on in production!
     26 DEBUG = True
     27 
     28 ALLOWED_HOSTS = []
     29 
     30 
     31 # Application definition
     32 
     33 INSTALLED_APPS = [
     34     'django.contrib.admin',
     35     'django.contrib.auth',
     36     'django.contrib.contenttypes',
     37     'django.contrib.sessions',
     38     'django.contrib.messages',
     39     'django.contrib.staticfiles',
     40     'app01.apps.App01Config',
     41     'rbac',
     42 ]
     43 from django.middleware.common import CommonMiddleware
     44 MIDDLEWARE = [
     45     'django.middleware.security.SecurityMiddleware',
     46     'django.contrib.sessions.middleware.SessionMiddleware',
     47     'django.middleware.common.CommonMiddleware',
     48     'django.middleware.csrf.CsrfViewMiddleware',
     49     'django.contrib.auth.middleware.AuthenticationMiddleware',
     50     'django.contrib.messages.middleware.MessageMiddleware',
     51     'django.middleware.clickjacking.XFrameOptionsMiddleware',
     52     'rbac.middlewear.rbac.Middle',
     53 ]
     54 
     55 ROOT_URLCONF = 'day80.urls'
     56 
     57 TEMPLATES = [
     58     {
     59         'BACKEND': 'django.template.backends.django.DjangoTemplates',
     60         'DIRS': [os.path.join(BASE_DIR, 'templates')]
     61         ,
     62         'APP_DIRS': True,
     63         'OPTIONS': {
     64             'context_processors': [
     65                 'django.template.context_processors.debug',
     66                 'django.template.context_processors.request',
     67                 'django.contrib.auth.context_processors.auth',
     68                 'django.contrib.messages.context_processors.messages',
     69             ],
     70         },
     71     },
     72 ]
     73 
     74 WSGI_APPLICATION = 'day80.wsgi.application'
     75 
     76 
     77 # Database
     78 # https://docs.djangoproject.com/en/1.11/ref/settings/#databases
     79 
     80 DATABASES = {
     81     'default': {
     82         'ENGINE': 'django.db.backends.sqlite3',
     83         'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
     84     }
     85 }
     86 
     87 
     88 # Password validation
     89 # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
     90 
     91 AUTH_PASSWORD_VALIDATORS = [
     92     {
     93         'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
     94     },
     95     {
     96         'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
     97     },
     98     {
     99         'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    100     },
    101     {
    102         'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    103     },
    104 ]
    105 
    106 
    107 # Internationalization
    108 # https://docs.djangoproject.com/en/1.11/topics/i18n/
    109 
    110 LANGUAGE_CODE = 'en-us'
    111 
    112 TIME_ZONE = 'UTC'
    113 
    114 USE_I18N = True
    115 
    116 USE_L10N = True
    117 
    118 USE_TZ = True
    119 
    120 
    121 # Static files (CSS, JavaScript, Images)
    122 # https://docs.djangoproject.com/en/1.11/howto/static-files/
    123 
    124 STATIC_URL = '/static/'
    125 # ==========静态文件配置=========
    126 STATICFILES_DIRS = (
    127     os.path.join(BASE_DIR,'static'),
    128 )
    129 # ==========rbac============
    130 PERMISSION_URL_DICT = "permission_url_list"
    131 PERMISSION_MENU_KEY = "permission_menu_list"
    132 
    133 # =========白名单(不需要权限就可以看到的)==========
    134 WHITE_LIST =[
    135      "/login/",
    136      "/admin.*",
    137      "/index/",
    138 ]
    settings.py

    2、rbac应用下的models

     1 from django.db import models
     2 
     3 # Create your models here.
     4 class Role(models.Model):
     5     title = models.CharField(max_length=32,verbose_name="角色")
     6     permissions = models.ManyToManyField(to="Permission",verbose_name="拥有权限的角色",blank=True)  #权限和角色是多对多的关系
     7 
     8     def __str__(self):
     9         return self.title
    10     class Meta:
    11         verbose_name_plural = "角色表"
    12 
    13 class Permission(models.Model):
    14     title = models.CharField(max_length=32,verbose_name="权限名")
    15     url = models.CharField(max_length=32,verbose_name="带正则的url")
    16     codes = models.CharField(max_length=32,verbose_name="代码")
    17     group = models.ForeignKey(to="Group",verbose_name="所属组",blank=True)  #组和权限是一对多的关系,一个组有多个权限
    18     menu_gp = models.ForeignKey(to='Permission',related_name='aaa',null=True,blank=True,verbose_name="组内菜单")
    19     def __str__(self):
    20         return self.title
    21     class Meta:
    22         verbose_name_plural = "权限表"
    23 
    24 class UserInfo(models.Model):
    25     name = models.CharField(max_length=32,verbose_name="姓名")
    26     password = models.CharField(max_length=64,verbose_name="密码")
    27     email = models.CharField(max_length=32,verbose_name="邮箱")
    28     roles = models.ManyToManyField(to="Role",blank=True)  #用户和角色是多对多的关系
    29     def __str__(self):
    30         return self.name
    31     class Meta:
    32         verbose_name_plural = "用户表"
    33 
    34 class Group(models.Model):
    35     title = models.CharField(max_length=32,verbose_name="组名称")
    36     menu = models.ForeignKey(to="Menu",verbose_name="组内菜单",blank=True)  #一个组下有多个菜单
    37     def __str__(self):
    38         return self.title
    39     class Meta:
    40         verbose_name_plural = ""
    41 
    42 class Menu(models.Model):
    43     caption = models.CharField(max_length=32,verbose_name="菜单")
    44     def __str__(self):
    45         return self.caption
    46     class Meta:
    47         verbose_name_plural = "菜单表"
    models.py

    3、urls

     1 from django.conf.urls import url
     2 from django.contrib import admin
     3 from app01 import views
     4 urlpatterns = [
     5     url(r'^admin/', admin.site.urls),
     6     url(r'^login/$', views.login),
     7     url(r'^index/$', views.index),
     8     url(r'^userinfo/$', views.userinfo),
     9     url(r'^userinfo/add/$', views.userinfo_add),
    10     url(r'^userinfo/del/(d+)/$', views.userinfo_del),
    11     url(r'^userinfo/edit/(d+)/$', views.userinfo_edit),
    12     url(r'^order/$', views.order),
    13     url(r'^order/add/$', views.order_add),
    14     url(r'^order/del/(d+)/$', views.order_del),
    15     url(r'^order/edit/(d+)/$', views.order_edit),
    16 ]
    urls.py

    4、初始化   server--init_permission

     1 #!usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 from django.conf import settings
     4 def init_permission(user, request):
     5     '''
     6     初始化权限信息,获取权限信息并放置到session中
     7     :param user:
     8     :param request:
     9     :return:
    10     '''
    11     permission_list = user.roles.values('permissions__id',
    12                                         'permissions__title',  # 用户列表
    13                                         'permissions__url',
    14                                         'permissions__codes',
    15                                         'permissions__menu_gp_id',  # 组内菜单ID,Null表示是菜单
    16                                         'permissions__group_id',
    17                                         'permissions__group__menu_id',  # 菜单ID
    18                                         'permissions__group__menu__caption',  # 菜单名称
    19                                         ).distinct()  # 获取当前角色对象的所有的权限并去重
    20     # print(permission_list)
    21     # 权限相关
    22     url_dict = {}
    23     for item in permission_list:
    24         group_id = item["permissions__group_id"]
    25         url = item["permissions__url"]
    26         code = item["permissions__codes"]
    27         # print("code_list", code)
    28         if group_id in url_dict:
    29             url_dict[group_id]["code"].append(code)  # 如果id在里面就把code和url添加进去
    30             url_dict[group_id]["urls"].append(url)
    31         else:
    32             # 如果不在就设置
    33             url_dict[group_id] = {
    34                 "code": [code, ],
    35                 "urls": [url, ]
    36             }
    37     request.session[settings.PERMISSION_URL_DICT] = url_dict
    38     print(url_dict)
    39 
    40 
    41     #菜单相关
    42     # 1、先去掉不是菜单的
    43     menu_list = []
    44     for item in permission_list:
    45         tpl = {
    46             "id":item["permissions__id"],
    47             "title":item["permissions__title"],
    48             "url":item["permissions__url"],
    49             "menu_gp_id":item["permissions__menu_gp_id"],
    50             "menu_id":item["permissions__group__menu_id"],
    51             "menu_title":item["permissions__group__menu__caption"]
    52         }
    53         menu_list.append(tpl)
    54     request.session[settings.PERMISSION_MENU_KEY] = menu_list
    55     print("============",menu_list)
    sever下的init_permission.py

    5、app01下的views

    views.py
     1 from django.shortcuts import render, redirect, HttpResponse
     2 from django.conf import settings
     3 # Create your views here.
     4 from rbac import models
     5 import re
     6 from rbac.service.init_permission import init_permission
     7 class BasePagPermission(object):
     8     def __init__(self, code_list):
     9         self.code_list = code_list
    10 
    11     def has_add(self):
    12         if "add" in self.code_list:
    13             return True
    14 
    15     def has_del(self):
    16         if "del" in self.code_list:
    17             return True
    18 
    19     def has_edit(self):
    20         if "edit" in self.code_list:
    21             return True
    22 
    23 
    24 def login(request):
    25     if request.method == "GET":
    26         return render(request, "login.html")
    27     else:
    28         username = request.POST.get("username")
    29         password = request.POST.get("password")
    30         user = models.UserInfo.objects.filter(name=username, password=password).first()
    31         if user:
    32             init_permission(user, request)
    33             return redirect("/userinfo/")
    34         else:
    35             return render(request, "login.html")
    36 
    37 
    38 def index(request):
    39     return render(request, "index.html")
    40 
    41 
    42 def userinfo(request):
    43     pagpermission = BasePagPermission(request.permission_code_url)  # 实例化
    44     # print("code......", request.permission_code_url)
    45     data_list = [
    46         {"id": 1, "name": "haiyan1"},
    47         {"id": 2, "name": "haiyan2"},
    48         {"id": 3, "name": "haiyan3"},
    49         {"id": 4, "name": "haiyan4"},
    50         {"id": 5, "name": "haiyan5"},
    51     ]
    52     #print("data_list",data_list)
    53     #print("pagpermission",pagpermission)
    54     return render(request, "userinfo.html", {"data_list": data_list, "pagpermission": pagpermission})
    55 
    56 
    57 def userinfo_add(request):
    58     if request.method == "GET":
    59         return render(request,"userinfo_add.html")
    60     else:
    61         return redirect("/userinfo/")
    62 
    63 
    64 def userinfo_del(request, nid):
    65     return HttpResponse("删除用户")
    66 
    67 
    68 def userinfo_edit(request, nid):
    69     return HttpResponse("编辑用户")
    70 
    71 
    72 def order(request):
    73     pagpermission = BasePagPermission(request.permission_code_url)  # 实例化
    74     print("code......", request.permission_code_url)
    75     return render(request,"order.html",{"pagpermission":pagpermission})
    76 
    77 
    78 def order_add(request):
    79     return HttpResponse("添加订单")
    80 
    81 
    82 def order_del(request, nid):
    83     return HttpResponse("删除订单")
    84 
    85 
    86 def order_edit(request, nid):
    87     return HttpResponse("编辑订单")
    views.py

    6、中间件

     1 #!usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 from django.shortcuts import render, redirect, HttpResponse
     4 from django.conf import settings
     5 import re
     6 
     7 
     8 class MiddlewareMixin(object):
     9     def __init__(self, get_response=None):
    10         self.get_response = get_response
    11         super(MiddlewareMixin, self).__init__()
    12 
    13     def __call__(self, request):
    14         response = None
    15         if hasattr(self, 'process_request'):
    16             response = self.process_request(request)
    17         if not response:
    18             response = self.get_response(request)
    19         if hasattr(self, 'process_response'):
    20             response = self.process_response(request, response)
    21         return response
    22 
    23 
    24 class Middle(MiddlewareMixin):  # 必须去继承这个类
    25     def process_request(self, request):
    26         current_url = request.path_info  # 获取当前请求的路径
    27 
    28         # 如果匹配的是白名单里面的就让通过,不需要权限
    29         for url in settings.WHITE_LIST:
    30             if re.match(url, current_url):
    31                 return None
    32         permission_dict = request.session.get(settings.PERMISSION_URL_DICT)  # 获取session
    33         if not permission_dict:  # 如果没有得到,就直接跳转到login页面
    34             return redirect("/login/")
    35 
    36         flag = False
    37         for group_id, code_url in permission_dict.items():
    38             for db_url in code_url["urls"]:
    39                 regex = "^{0}$".format(db_url)
    40                 # 因为match匹配的时候会把你只要有的都匹配到了,我们只匹配当前的url,所以得加一个起始终止符
    41                 # print(regex, current_url)
    42                 if re.match(regex, current_url):
    43                     # print(1111111)
    44                     request.permission_code_url = code_url["code"]  # 用户输入的url和数据库的url匹配成功之后成功之后先把code保存在request中,方便以后判断
    45                     flag = True
    46                     break  # 如果匹配成功就进入页面
    47                     # 注意在这里不能用return,在中间件中process_request这个函数如果有return就只会执行自己的
    48                     #   response和上面的response,不会执行后续的。没有return就会去继续执行后续中间件和视图函数
    49             if flag:  # 结束外层循环
    50                 break
    51         if not flag:
    52             return HttpResponse("无权访问")  # 如果访问不成功就显示无权访问
    53 
    54     def process_reponse(self, request, response):
    55         return response
    middlewear下的rbac.py

    7、templatetags下的rbac.py

     1 #!usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 from django.conf import settings
     4 import re
     5 from django.template import Library
     6 register = Library()
     7 @register.inclusion_tag("xxxx.html")
     8 def menu_html(request):
     9     """
    10        去Session中获取菜单相关信息,匹配当前URL,生成菜单
    11        :param request:
    12        :return:
    13        """
    14     menu_list = request.session.get(settings.PERMISSION_MENU_KEY)
    15     current_url = request.path_info
    16     menu_dict = {}
    17     for item in menu_list:
    18         # 循环找到可以作为菜单的权限
    19         if not item["menu_gp_id"]:
    20             menu_dict[item["id"]] = item
    21     # 正则匹配添加active
    22     for item in menu_list:
    23         regex = "^{0}$".format(item["url"])
    24         if re.match(regex, current_url):
    25             # 匹配成功在根据id去判断,如果菜单id有值就不是菜单,则去找它的值对应的id,添加active
    26             # ,为null时就是菜单,直接给自己添加一个active
    27             if not item["menu_gp_id"]:  #是菜单
    28                 menu_dict[item["id"]]["active"] = True
    29             else:
    30                 menu_dict[item["menu_gp_id"]]["active"] = True
    31 
    32     result = {}
    33     for item in menu_dict.values():
    34         active = item.get("active")
    35         menu_id = item["menu_id"]
    36         if menu_id in result:
    37             result[menu_id]["children"].append({'title': item['title'], 'url': item['url'], 'active': active})
    38             if active:
    39                 result[menu_id]["active"] = True
    40         else:
    41             result[menu_id] = {
    42                 'menu_id': item['menu_id'],
    43                 'menu_title': item['menu_title'],
    44                 'active': active,
    45                 'children': [
    46                     {'title': item['title'], 'url': item['url'], 'active': active}
    47                 ]
    48             }
    49     print("result",result)
    50     return {"menu_dict":result}
    自定义标签rbac.py

    8、template

     1 {% load rbac %}
     2 <!DOCTYPE html>
     3 <html lang="en">
     4 <head>
     5     <meta charset="UTF-8">
     6     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     7     <meta name="viewport" content="width=device-width">
     8     <title>Title</title>
     9     <link rel="stylesheet" href="/static/rbac/rbac.css">
    10 </head>
    11 <body>
    12 <div class="aaa">
    13     <div class="left">
    14         {% menu_html request %}
    15     </div>
    16     <div class="right">
    17         {% block content %}
    18 
    19         {% endblock %}
    20     </div>
    21 </div>
    22 <script src="/static/jquery-3.2.1.min.js"></script>
    23 <script src="/static/rbac/rbac.js"></script>
    24 
    25 </body>
    26 </html>
    base.html
     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     6     <meta name="viewport" content="width=device-width">
     7     <title>Title</title>
     8 </head>
     9 <body>
    10 <h1>hello--{{ user.name }}</h1>
    11 </body>
    12 </html>
    index.html
     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     6     <meta name="viewport" content="width=device-width">
     7     <title>Title</title>
     8 </head>
     9 <body>
    10 <form method="post" action="/login/">
    11     {% csrf_token %}
    12     <p>姓名:<input type="text" name="username"></p>
    13     <p>密码:<input type="password" name="password"></p>
    14     <p><input type="submit" value="提交"></p>
    15 </form>
    16 </body>
    17 </html>
    login.html
    1 {% extends "base.html" %}
    2 {% block content %}
    3 <h1>订单页面</h1>
    4 {% endblock %}
    order.html
     1 {% extends "base.html" %}
     2 {% block content %}
     3 {% if pagpermission.has_add %}
     4         <a href="/userinfo/add/">添加</a>
     5         {% endif %}
     6         <table border="1">
     7             <thead>
     8                 <th>编号</th>
     9                 <th>姓名</th>
    10                 <th>操作</th>
    11             </thead>
    12             <tbody>
    13             {% for row in data_list %}
    14                 <tr>
    15                     <td>{{ row.id }}</td>
    16                     <td>{{ row.name }}</td>
    17                     <td>
    18                         {% if pagpermission.has_edit %}
    19                          <a href="#">编辑</a>
    20                         {% endif %}
    21                        {% if pagpermission.has_del %}
    22                         <a href="#">删除</a>
    23                        {% endif %}
    24                     </td>
    25                 </tr>
    26             {% endfor %}
    27             </tbody>
    28         </table>
    29 {% endblock %}
    userinfo.html
    1 {% extends "base.html" %}
    2 {% block content %}
    3 <form action="" method="post">
    4     {% csrf_token %}
    5     <p>编号:<input type="text" name="bianhao"></p>
    6     <p>姓名:<input type="text" name="name"></p>
    7     <input type="submit" value="提交">
    8 </form>
    9 {% endblock %}
    userinfo_add.html
     1 {% for k,item in menu_dict.items %}
     2  <div class="item-title">{{ item.menu_title }}</div>
     3      {% if item.active %}
     4             <div class="item-permission">
     5         {% else %}
     6             <div class="item-permission hide">
     7         {% endif %}
     8         {% for v in item.children %}
     9             {% if v.active %}
    10                     <a href="{{ v.url }}" class="active">{{ v.title }}</a>
    11             {% else %}
    12                     <a href="{{ v.url }}">{{ v.title }}</a>
    13             {% endif %}
    14         {% endfor %}
    15     </div>
    16 {% endfor %}
    17 
    18 {# <div class="item-title">菜单一</div>#}
    19 {#        <div class="item-permission">#}
    20 {#            <a href="">用户列表</a>#}
    21 {#            <a href="">订单列表</a>#}
    22 {#        </div>#}
    23 {#    <div class="item-title">菜单二</div>#}
    24 {#        <div class="item-permission hide">#}
    25 {#            <a href="">用户列表</a>#}
    26 {#            <a href="">订单列表</a>#}
    27 {#        </div>#}
    xxxx.html

    9、static---rbac---rbac.css

     1 .left{
     2     float: left;
     3      20%;
     4     height: 500px;
     5     background-color: coral;
     6     padding: 20px 20px;
     7 }
     8 .right{
     9      80%;
    10     height: 500px;
    11     background-color: azure;
    12 }
    13 .item-permission a{
    14     display: block;
    15 }
    16 .hide{
    17     display: none;
    18 }
    19 .item-permission a.active{
    20     color: red;
    21 }
    rbac.css

    10、static---rbac---rbac.js

     1  // 方式一
     2 $(function () {
     3         $(".item-title").click(function () {
     4               $(this).next().toggleClass("hide")
     5         })
     6     });
     7 // 方式二:
     8 //  $(function () {
     9 //     $('.item-title').click(function () {
    10 //         if($(this).next().hasClass('hide')){
    11 //             $(this).next().removeClass('hide')
    12 //         }else{
    13 //             $(this).next().addClass('hide')
    14 //         }
    15 //     })
    16 //  });
    rbac.js
     
     
  • 相关阅读:
    洛谷 P1226 【模板】快速幂||取余运算 题解
    洛谷 P2678 跳石头 题解
    洛谷 P2615 神奇的幻方 题解
    洛谷 P1083 借教室 题解
    洛谷 P1076 寻宝 题解
    洛谷 UVA10298 Power Strings 题解
    洛谷 P3375 【模板】KMP字符串匹配 题解
    Kafka Shell基本命令
    Mybatis与Hibernate的详细对比
    MyBatis简介
  • 原文地址:https://www.cnblogs.com/xiaole-7890/p/10144382.html
Copyright © 2011-2022 走看看