django权限组件

1.权限设计

复制代码
    权限表设计
        id    url
        1     /user_list/
        2     /customer_list/
    用户表设计
        id username password
        1  root     root@123
        2  admin     root@123
    用户和权限的关系表
        id user_id perssion_id
        1  1       1
        2  1       2
    这种表结构随着权限的增加,用户和权限的表关系的表会越来越大。所以我们要添加一个角色表。每个角色有不同的权限。
复制代码

所以要变成下面的表结构

rbac:基于角色的访问控制

2.rbac组件的设计

复制代码
我们可以将组件设计成app的类型,方便以后重用。
1.创建组件app
  python manage.py startapp rbac
  创建之后要注册app。如果单独使用文件的话,就不需要注册,直接导入就可以。如果注册的话,django就会认识这个app(注册不不注册的却别)

2.设计表结构
  在rbac里面的models.py写表结构
复制代码
from django.db import models

# Create your models here.

class Permission(models.Model):
    url = models.CharField(verbose_name='权限',max_length=108)
    title = models.CharField(verbose_name='权限的名字',max_length=32)

    def __str__(self):
        return self.title

class Role(models.Model):
    name = models.CharField('角色名称',max_length=32)
    permissions = models.ManyToManyField('Permission',verbose_name='角色拥有的权限',blank=True) # 会通过角色查找权限的次数较多 blank=True,django-admin里面可以为空

    def __str__(self):
        return self.name

class User(models.Model):
    username = models.CharField('用户名',max_length=32)
    password = models.CharField('密码',max_length=32)
    role = models.ManyToManyField('Role',verbose_name='用户拥有的角色')  # 通过用户查询角色会多一点

    def __str__(self):
        return self.username
View Code
复制代码
  数据库命令: python manage.py makemigrations,python manage.py migrate

3.使用django-admin录入信息
  3.1 在rbac的admin.py下面写入django-admin的注册信息
    
from django.contrib import admin
    from rbac import models
    # Register your models here.
    admin.site.register(models.User)
    admin.site.register(models.Permission)
    admin.site.register(models.Role)
  
3.2 创建超级用户
    python manage.py createsuperuser
  3.3 在rbac下的admin.py里面注册数据表
复制代码
from django.contrib import admin
from rbac import models
# Register your models here.
# 配置类,帮我们在admin里面更好的展示数据内容,是resister的第二个参数
class PermissionAdmin(admin.ModelAdmin):
    list_display = ['title','url']   # 要展示的字段
    list_editable = ['url']    # 在admin展示时可以编辑
admin.site.register(models.User)
admin.site.register(models.Permission,PermissionAdmin)
admin.site.register(models.Role)
View Code
复制代码
   3.4 登录django-admin后台,就可以增加数据
复制代码

 3.权限控制流程与思路

复制代码
按照流程来解释每一个阶段的作用:
  1.process_request
    使用process_request中间件,通过获取用户session来判断用户是否有权限访问该url
    注意:是所有的url地址都要通过process_request中间件。
  2.白名单
    未登录情况下,所有的访问都无权限,因为后端视图函数还没有设置session,所以要设置白名单来放行login,register等不需要登录的功能。
  3.免认证地址校验
    在后端登录成功时,后端会跳转到一个页面,但是不知道要跳转的是哪里。假如说是index页面,跳转之后还是会从process_request中间件经过,我们可以设置给当前用户一个免认证的地址(一般是首页,或修改密码等)。
    在首页上面会有真正需要进行权限校验的url地址。
  4.免认证和白名单的区别
    区别在于是否是登陆成功!
  5.登录
    验证当前用户是否成功登陆
    成功登陆
      1.就跳转到免认证里面设置的url地址
      2.并且记录登录状态is_login,这个在免认证时要是用,免认证根据是否登陆成功来决定放行与否。
      3.在数据库中读取当前用户的权限,封装到session里面。等待中间件process_request使用session验证用户是否有权限登录其他url地址。
    登录失败,跳转到login,继续登录

 整体思路就是两部分:
    1.在登录时,如果登录成功,则保存当前用户的权限信息
    2.在访问时,在中间件校验权限信息

复制代码

4.中间件权限校验 

复制代码
其实也可以不写中间件,用装饰器函数来代替,但是这样就每次请求都会在后端来校验写中间件的好处是,请求先经过中间件来校验,可以阻挡很多流量。
rbac.py 中间件
复制代码
# -*- coding: utf-8 -*- 
# @Time    : 2019/9/24 21:06 
# @Author  : p0st
# @Site    :  
# @File    : rbac.py
# @Software: PyCharm
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import reverse,HttpResponse,redirect
from django.conf import settings  # 导入settings
import re
class RbacMiddleWare(MiddlewareMixin):
    def process_request(self,request):
        # 获取当前访问地址
        url = request.path_info
        # 白名单
            # 这样写的缺点是,下一个白名单还是需要些这段代码,我们可以直接用一个列表来承接所有表名单url,
            # 但是最好的解决办法是在settings里面配置一个白名单变量,通过正则来匹配
            # whith_url = [reverse('login')]
            # if url in whith_url:
            #     return   # 等于none的时候process_request才会走向下一个中间件,是正常流程
        for item in settings.WHITE_LIST:
            if re.match(item,url):   # re.match匹配成功的话是一个对象,匹配失败的话,结果是一个None
                return
        # 登录状态校验
        is_login = request.session.get('is_login')
        if not is_login:
            return redirect('login')
        # 免认证校验, 必须是含有登录状态True
        # not_auth_Url_list = [reverse('index'),reverse('logout')]
        for item in settings.NOT_AUTH_URL_LIST:
            if re.match(item,url):
                return
        # 获取权限信息
        permissions = request.session['permissions']
        print(permissions)
        # 权限的验证
        for item in permissions:
            if re.match(r'^{}$'.format(item['permissions__url']),url):   # macth ^ 可以不写,默认是^ 尖角号开头
                return
        return HttpResponse('没有访问权限~,请联系管理员~')
复制代码
全部代码
复制代码

other

1.模板和静态文件查找顺序
   'DIRS': [os.path.join(BASE_DIR, 'templates')]
    模板在默认的templates里面取找,找不到去注册的app顺序去找templates文件夹,静态文件static也是一样的查找顺序
2.queryset对象不能进行json序列化
3. re.match()默认匹配成功返回一个对象,匹配不成功,返回一个None。默认就带^

pass

 

posted @   thep0st  阅读(59)  评论(0编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类
点击右上角即可分享
微信分享提示