权限的设计分析和基本使用

浏览目录

 

权限介绍

一、什么是权限

权限咱们应该不陌生,不同的人权限不一样,咱们常说“官大一级压死人”,就是说每个职位权限不一样。咱们常常会碰到说必须是管理员才能操做,这就是管理员的一种权限。什么是权限呢?总的来讲,在咱们项目中,就是一个包含正则表达式的URL就是一个权限。css

咱们简称为RBAC。(url base access control)。html

二、做用

权限的做用,就是生成一个独立的组件,咱们想用时均可以用。python

权限在Django中的操做

说了这么多也不必定会用,下面咱们来看一个在Django框架中的实例。jquery

新建项目

咱们新建一个project_rbac项目,再建两个app分别为app01和rbac,app01专门放与项目相关逻辑方面的应用,而rbac专门放与权限相关的。正则表达式

记得在settings.py中配置新建的项目。数据库

配置app

配置静态文件

STATIC_URL = '/static/'

STATICFILES_DIRS=[
    os.path.join(BASE_DIR,"static")
]  

建立表关系

rbac.models.pydjango

建三个类,五张表bootstrap

# 用户表
class UserInfo(models.Model):
    name = models.CharField(max_length=32)
    pwd = models.CharField(max_length=32)
    roles = models.ManyToManyField(to="Role")      #用户与角色是多对多的关系

    def __str__(self):
        return self.name


# 角色表
class Role(models.Model):
    title = models.CharField(max_length=32)
    permissions = models.ManyToManyField(to="Permission")    #角色与权限多对多的关系

    def __str__(self):
        return self.title

# 权限表
class Permission(models.Model):
    title = models.CharField(max_length=32)
    url = models.CharField(max_length=32)

    def __str__(self):
        return self.title

角色表和权限表是多对多的关系(一个角色能够有多个权限,一个权限能够对应多个角色)
用户表和角色表是多对多的关系(一个用户能够有多个角色,一个角色有多个用户)  session

 基于admin录入数据

- 先建立一个超级用户 python3 manage.py createsuperuser
    - 用户名 root
    - 密码 123456
    - 在admin.py 中
        from rbac import models
        admin.site.register(models.Permission)
        admin.site.register(models.Role)
        admin.site.register(models.UserInfo)
      这样的话上去的是英文的,若是你想让中文显示就在类中加一个类
        class Meta:
           verbose_name_plural = "权限表"
      - 当你给关联字段录入数据的时候会有错误提示,那么在类中你的那个关联字段在加一个属性blank = True 能够为空
      permissions = models.ManyToManyField(to="Permission",verbose_name="具备的全部权限", blank=True)

登陆校验

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>登陆</title>
    {% load static %}
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="{% static "bs/css/bootstrap.css" %}">
    <style>
        .container{
            margin-top: 150px;
        }
    </style>
</head>
<body>



<div class="container">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <div class="panel panel-primary">
                <div class="panel-heading">登陆页面</div>
                <div class="panel-body">
                    <form action="" method="post">
                        {% csrf_token %}
                        <div class="form-group">
                            <label for="user">用户名</label>
                            <input type="text" class="form-control" id="user" name="user" placeholder="请输入用户名">

                        </div>

                        <div class="form-group">
                            <label for="pwd">密码</label>
                            <input type="password" class="form-control" id="pwd" name="pwd"  placeholder="请输入密码">
                        </div>


                        <input type="submit" class="btn btn-primary login_btn" value="登陆">
                    </form>

                </div>

            </div>
        </div>
    </div>
</div>
<script src="{% static '/js/jquery-3.2.1.min.js' %}"></script>
<script src="{% static '/bs/js/bootstrap.js' %}"></script>
</body>
</html>
login.html

在rbac应用下面新建service包,新建perssions.py.app

def initial_session(user,request):
    ## 查询当前登陆用户的全部权限
    permissions = user.roles.all().values("permissions__url").distinct()  # 权限列表去重
    permission_list = []
    for item in permissions:  # 循环取到的全部权限
        permission_list.append(item["permissions__url"])  # 将该用户的权限url添加到permission_list列表中
    print(permission_list)
    # 在session中注册权限列表
    request.session["permission_list"] = permission_list
views.py视图中
# 登陆
def login(request):
    if request.method == "POST":
        user = request.POST.get("user")  # 取到输入的用户名
        pwd = request.POST.get("pwd")  # 取到输入的密码

        user = UserInfo.objects.filter(name=user, pwd=pwd).first()  # 判断该用户是否存在于数据库
        if user:  # 登陆成功
            # 在session中注册用户ID
            request.session["user_id"] = user.pk

            # 查询当前登陆用户的全部角色
            # user_list= user.roles.all()  #角色列表        <QuerySet [<Role: 保洁>, <Role: 销售>]>

            # 查询当前登陆用户的全部权限
            initial_session(user,request)

            return HttpResponse("登陆成功")

    return render(request, "login.html")   

权限校验

在rbac应用下面新建service包,新建rbac.py,做为中间件。

在settings中配置中间件。

rbac.py
import re
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse, redirect

'''中间件'''

class ValidPermission(MiddlewareMixin):
    def process_request(self, request):
        # 当前访问路径
        current_path = request.path_info

        '''检查是否属于白名单'''
        valid_url_list = ["/login/", "/reg/", "/admin/.*"]  # 白名单列表
        for url in valid_url_list:  # 查看是否属于白名单
            ret = re.match(url, current_path)  # 当前路径与白名单列表作匹配
            if ret:  # 当前路径属于白名单
                return None  # 经过这个校验

        '''校验是否登陆
            '''
        user_id = request.session.get("user_id")  # 取到当前登陆用户的id值
        if not user_id:  # 取不到id,说明没登陆,跳转到登陆页面,从新登陆
            return redirect("/login/")

        '''校验权限'''
        permission_list = request.session.get("permission_list", [])
        flag = False  # 设置初始值
        for permission in permission_list:  # 循环权限列表,查看权限
            permission = "^%s$" % permission  # 字符串拼接从新定义权限
            ret = re.match(permission, current_path)  # 权限路径与当前访问路径作匹配
            if ret:  # 匹配成功
                flag = True  # 改变状态,跳出循环
                break
        if not flag:
            return HttpResponse("很差意思,您没有访问权限!")

        return None

 设置白名单,是指全部人均可以访问的url。登陆校验,在访问某一些url时,只有登陆才能访问,若是没登陆,跳转到登陆页面。权限校验,判断当前登陆用户有哪些权限,对于没有该权限的用户,是无访问的。 

相关文章
相关标签/搜索