Django:RBAC角色管理

模型类

# 用户表
class UserModel(models.Model):
    user_name = models.CharField('用户名字', max_length=16)
    root = models.CharField('账号', max_length=16)
    phone = models.CharField('手机号', max_length=16)
    password = models.CharField('用户密码', max_length=256)
    role = models.ForeignKey('RoleModel', on_delete=models.CASCADE)



# 角色表 (一个角色有多个权限,一个权限被多个角色使用)
class RoleModel(models.Model):
    role_name = models.CharField('角色名字', max_length=16)


# 权限表 (path添加格式:/primary/userinfo/  method添加格式:GET)
class AccessModel(models.Model):
    access_name = models.CharField('用户权限名称', max_length=256)
    access_path = models.CharField('用户权限路由', max_length=256)
    access_method = models.CharField('用户权限请求方式', max_length=16)


# 角色-权限 多对多
class RoleAccessModel(models.Model):
    role_id = models.IntegerField('角色ID', null=True, blank=True)
    acc_id = models.IntegerField('权限ID', null=True, blank=True)

装饰器

import jwt
import redis
from rest_framework.response import Response

from OA_pro import settings
from primary.models import UserModel, RoleAccessModel, AccessModel


def check_login(func):
    def wrapper(self, request, *args, **kwargs):
        # 设置白名单路由(除登录注册等基本页面以外,尽量放token验证后面)
        if request.path == '/primary/login/' or request.path == '/primary/smscode/':
            return func(self, request, *args, **kwargs)

        # token验证
        token = request.headers.get('token')
        # 判断token是否已经被禁用
        rds = redis.Redis(host='127.0.0.1', port=6379)
        is_exists = rds.exists('token_%s' % token)  # exists判断键是否存在
        if is_exists:  # redis中有这个token 代表此token已禁用
            return Response({
                'code': 403, 'msg': '此token不可使用'
            })
        try:
            payload = jwt.decode(token, key=settings.SECRET_KEY, algorithms='HS256')
        except:
            return Response({
                'code': 403, 'msg': '用户未登录'
            })

        request.user_id = payload.get('user_id')
        request.user = UserModel.objects.filter(id=request.user_id).first()

        # 路由访问权限验证
        # 创建该用户在(角色-权限 多对多表)的查询结果集
        role_access_list = RoleAccessModel.objects.filter(role_id=request.user.role_id).all()
        # (如果该角色没有配置任何路由,role_access_list会为空)
        if not role_access_list:
            return Response({
                'code': 401, 'msg': '您没有访问权限!'
            })
        # 设置一个管理员权限(访问所有)
        if role_access_list[0].acc_id == 1:
            return func(self, request, *args, **kwargs)
        acc_info_list = []

        for role_access in role_access_list:
            acc_id = role_access.acc_id
            acc_info = AccessModel.objects.filter(id=acc_id).first()
            # 添加该用户所有权限对象
            acc_info_list.append(acc_info)
        global flag
        flag = False
        # 获取当前路由
        path = request.path
        # 获取当前请求方式
        method = request.method
        for access in acc_info_list:
            if access.access_path.upper() == path.upper() and access.access_method.upper() == method.upper():
                flag = True
        if not flag:
            return Response({
                'code': 401,
                'message': "您没有访问权限!"
            })

        return func(self, request, *args, **kwargs)

    return wrapper

用户表 

角色表: 

 

权限表: 

角色---权限(多对多,公共表) 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值