前后端分离 通用鉴权方案 (分组权限)

前后端分离 通用鉴权方案 (分组权限)

前言

做了几个前后端分离的项目,都遇到了权限管理的问题。这里总结一下实现的方案及注意事项。

问题

鉴权的需求一般是这样的,假设有 A(主页), B, C, D(系统配置页) 四个页面:

  • 超级管理员能访问所有页面
  • 一类管理人员访问AB页面
  • 二类管理人员访问AC页面
  • 测试人员访问能访问某几个指定页面 AB
  • 普通用户只能访问A

用户与页面是多对多的关系,相互之间会有交叉,所以使用简单的分级权限实现起来是很麻烦的。如果新增一个用户,使其能访问ABC,就需要新建一个分级,使其只有ABC的权限。假设某一天又有用户需要访问 ACD呢?

因此,在权限有交叉的情况下,使用分组权限是比较好的方案。

分组权限

分组权限的核心思想可以用下图表示

在这里插入图片描述

  • 用户与分组, 分组与权限都是多对多关系
  • 鉴权针对分组

这么说有点抽象,我们还是结合之前的例子,看用分组权限怎么解决。

  1. 系统建立 超级管理员、一类管理员、二类管理员、测试员、普通用户 几个分组。
  2. 用户和分组之间 通过 用户-分组 表建立多对多关系
  3. 页面设置 针对用户的分组进行鉴权,通过则允许访问

Talk is cheap, show me the code

下面用程序员最喜欢的方式来解释一下

from typing import List

# 分组表
groups = {
    1: '超级管理员',
    2: '一类管理员',
    3: '二类管理员',
    4: '测试员',
    5: '用户'
}

# 用户表
users = {
    1: '用户A',
    2: '用户B',
    3: '用户C'
}

# 用户分组表
user_group = {
    1: [1],    # 用户A -> 超级管理员
    2: [2],    # B -> 一类管理员
    3: [3, 4]  # C -> 一类管理员、测试员
}

# 页面及允许的用户组
pages = [
    {
        'name': '首页',
        'allow': None  # 表示所有用户均可看到
    },
    {
        'name': '页面1',
        'allow': ['超级管理员', '一类管理员', '测试员']
    },
    {
        'name': '页面2',
        'allow': ['超级管理员', '二类管理员', '测试员']
    },
    {
        'name': '设置页',
        'allow': ['超级管理员']
    }
]

def get_group_names_by_uid (uid: int) -> List[str]:
    """
    通过uid获取权限组列表
    """
    res = []
    for gid in user_group[uid]:  # 取出用户对应的权限组列表并转换为组名列表
        res.append(groups[gid])
    return res

def auth (user_access: List[str], page_auth: List[str]) -> bool:
    """
    两个集合是否有交集,有则通过
    """
    if not page_auth:  # 页面不鉴权
        return True

    for g in user_access:
        for a in page_auth:  # 因为元素很少,所以直接暴力双循环也很快
            if g == a:
                return True
    
    return False

if __name__ == "__main__":
    for uid, name in users.items():  # 用户尝试访问所有页面
        for page in pages:
            access = get_group_names_by_uid(uid)  # 查出用户的权限组
            print(name, ' 访问:', page['name'], '通过' if auth(access, page['allow']) else '未通过')
        
        print('\n')

最佳时间及注意事项

待续

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值