权限管理

low版权限管理结构

图片.png

1.创建rbac应用

1.先看配置文件合适不,给创建的rbac在配置文件里面设置一下找到
INSTTLED_APPs=['rbac']


图片.png

2.配置静态文件


图片.png

2.在models中创建对象

models
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)
    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)
    class Meta:
        verbose_name_plural = "角色表"

    def __str__(self):
        return self.title

models

3.基于Django admin录入权限数据

注意录入信息要先创建个超级用户

 python3 manage.py createsuperuser
-用户名 root
-密码:peak2345

注意;需要在admin.py中做如下操作(只针对从用admin导入数据的时候配置,当然也可以直接添加)

from django.contrib import admin
from . import models
admin.site.register(models.Permission)
admin.site.register(models.User)
admin.site.register(models.Role)

4.用户登录程序

根据输入的用户名和密码的到相应的user
根据user对象获取其拥有的角色和权限并去重并将权限表的url放入session中,将这部分操作的代码抽取到service包下的init_permission.py下的init_permission(request,user)方法中,然后在views中调用该方法既可

  • 获取当前用户具有的所有权限(去重)
  • 获取权限中的url,放置到session中
def init_permission(user,request):
    """
    初始化权限信息,获取权限信息并放置到session中。
    :param user:
    :param request:
    :return:
    """
    permission_list = user.roles.values('permissions__title', 'permissions__url', 'permissions__is_menu').distinct()
    url_list = []
    for item in permission_list:
        url_list.append(item['permissions__url'])
    print(url_list)
    request.session['permission_url_list'] = url_list

init_permission.py

4.中间件的使用

如果不用中间件会有好多个函数,就有许多重复的代码,这样我们可以用中间件来完成
中间件和装饰器的区别:

  • 中间件用来做批量处理
  • 如果函数不多的话可以用加装饰器的方法
import re
#:用re去匹配的时候,re.match(/userinfo/,/userinfo/add) #都能匹配到
from django.shortcuts import redirect,HttpResponse
from django.conf import settings

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

        # 当前请求不需要执行权限验证(白名单)
        for url in settings.VALID_URL:
            if re.match(url,current_url):
                return None

        permission_list = request.session.get("permission_url_list")
        if not permission_list:
            return redirect('/login/')

        flag = False
        for db_url in permission_list:
            regax = "^{0}$".format(db_url)
           #:那么要记得在匹配正则的时候加个起始符和终止符regex = "^{0}$".format(url)
            if re.match(regax, current_url):
                flag = True
                break

        if not flag:
            return HttpResponse('无权访问')

rbac.py

a.获取当前访问的路径 request.path_info
b.在setting中配置不需要验证的url--白名单(人人登录后都能访问如login admin)然后调用

VALID_URL = [
    "/login/",
    "/admin.*"
]

根据正则判断当前路径是否在白名单中,白名单中的路径要严格控制以什么开头和什么结尾,如果有白名单return none继续执行后面代码如果不是直接跳转到登录
c.不是白名单的话,则要判断是否登录,最简单的方法就是获取session
看里面是否为空,如果为空的话说明没有登录直接跳转到登录,不让他执行后续的操作
d.url list不为空的话就说明已经登陆了,进一步看当前的访问路径是否在是否在urllist中,在的话就说明用户具有操作该url的权限否则就说明该用户没有
访问权限,直接return HttpResponse("无权访问")
注意:中间件创建完成之后。需要在settings中的MIDDLEWARE最后添加'rbac.middlewares.rbac.RbacMiddleware',

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',
]

你可能感兴趣的:(权限管理)