1 permission权限控制

1 创建项目

参见nb博客:https://www.cnblogs.com/wupeiqi/articles/9178982.html

1 使用pycharm创建虚拟环境:


2 创建项目:

pip install Django==3.2
django-admin startproject crm_permission .

3 创建两个APP:rbac权限组件、web销售管理系统:

python manage.py startapp rbac
python manage.py startapp web

4 在settings.py配置:

INSTALLED_APPS = [
    ...
    'rbac.apps.RbacConfig',
    'web.apps.WebConfig',
]

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'crm_permission',  # 要连接的数据库,连接前需要创建好
        'USER': 'root',  # 连接数据库的用户名
        'PASSWORD': '',  # 连接数据库的密码
        'HOST': '127.0.0.1',  # 连接主机,默认本级
        'PORT': 3306  # 端口 默认3306
    }
}

5 roleAPP中models表创建:

models.py
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

6 webAPP代码呈现

image

image


点击下载-示例代码1


2 权限代码编写

以上简易版客户管理系统中的URL有:

客户管理
客户列表:/customer/list/
添加客户:/customer/add/
删除客户:/customer/list/(?P\d+)/
修改客户:/customer/edit/(?P\d+)/
批量导入:/customer/import/
下载模板:/customer/tpl/

账单管理
账单列表:/payment/list/
添加账单:/payment/add/
删除账单:/payment/del/(?P\d+)/
修改账单:/payment/edit/<?P\d+/

那么接下来,我们就在权限组件中录入相关信息:

  • 录入权限
  • 创建用户
  • 创建角色
  • 用户分配角色
  • 角色分配权限

2-1 基于admin录入信息

python manage.py createsuperuser  # 创建超级用户

在rbacAPP下admin.py文件下配置:

from django.contrib import admin
from . import models


admin.site.register(models.Permission)
admin.site.register(models.Role)
admin.site.register(models.UserInfo)

权限的录入:
image


角色的权限录入:
image


用户的角色录入:
image


已录入权限信息的代码下载


3 快速完成基本权限控制

image

快速实现简单的权限控制的设计思路:

第一次请求:用户输入用户名密码提交---->中间件---->视图---->在到数据库检验数据是否合法,如果成功,从数据库中拿到当前用户的所有权限并放入到session中

第二次请求:用户访问---->中间件判断当前用户访问的url在不在自己的session中---->成功后进入视图

3-1 用户登录

POST请求,用户登录是否合法。获取当前用户的所有权限放入session

login.html
<h3>用户登录</h3>
<form action="" method="post">
    {% csrf_token %}
    <input type="text" name="user">
    <input type="password" name="pwd">
    <input type="submit" value="提交"><span style="color: red">{{ msg }}</span>
</form>
urls.py
from django.urls import re_path

urlpatterns = [
    ...
    re_path(r'^login/', account.login),
]
account.py
from django.shortcuts import render, HttpResponse, redirect
from rbac import models


def login(request):
    if request.method == "GET":
        return render(request, "login.html")

    user = request.POST.get("user")
    pwd = request.POST.get("pwd")

    current_user = models.UserInfo.objects.filter(name=user, password=pwd).first()
    if not current_user:
        return render(request, "login.html", {"msg": "用户名密码错误"})

    # 根据当前用户信息获取此用户拥有的所有权限
    permission_queryset = current_user.roles.filter(permissions__isnull=False).values(
        "permissions__id",
        "permissions__url").distinct()

    # 获取权限中所有的url,写入session
    permissions_list = [item["permission__url"] for item in permission_queryset]
    request.session["crm_permission_url_list"] = permissions_list

    return redirect("/customer/list/")

4 权限校验

简易版的权限控制:

xxx.py
import re

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse


class CheckPermission(MiddlewareMixin):
    """用户权限信息的校验"""
    def process_request(self, request):
        # 获取当前用户请求的url
        # http://127.0.0.1:8000/customer/list/         ----> /customer/list/
        # http://127.0.0.1:8000/customer/list/?age=19  ----> /customer/list/
        current_url = request.path_info

        # 是否存在于白名单中
        valid_url_list = ["/login/", "/admin/.*", ]
        for valid_url in valid_url_list:
            if re.match(valid_url, current_url):
                return None  # 执行后续函数

        # 获取当前用户在session中保存的权限列表
        permission_list = request.session.get("crm_permission_url_list")
        if not permission_list:
            return HttpResponse("未获取到用户权限信息,请登录!")

        # 权限信息的匹配
        flag = False
        for url in permission_list:
            reg = "^{}$".format(url)
            if re.match(reg, current_url):
                flag = True
                break

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

优化版:含用户登录的源码下载

posted @ 2022-08-25 11:06  角角边  Views(56)  Comments(0Edit  收藏  举报