权限和角色

概念

每个用户都有自己的权利,能干什么不能干什么,这就是权限

User1有权限ABC
User2有权限ABC
User3有权限ABCD
User4有权限DF

有多个用户,可能拥有同样的权限,可以认为他们是一组

P1组有权限ABC
P2组有权限DF
User1属于P1组,就直接拥有了ABC权限
User2属于P1组,也就直接拥有了ABC权限
User3属于P1组,也就直接拥有了ABC权限,单独再为User3赋予D权限即可
User4属于P2组,就直接拥有了DF权限

从上面分析可知,有用户、组、权限,他们形成了关系。组就是角色,很多用户都可以赋予该角色。

这种基于角色的权限设计成为RBAC(Role-Based Access Control)

复杂设计:用户自身有权利,用户还可以同时属于组,获得组的权利。

简单设计:用户必须属于组,获得组的权利。

Django实现了复杂的设计,但是可以简化。

Django权限设计

image

Django权限表

  • 用户和组,属于多对多关系。一个用户可以属于多个组,一个组可以有多个用户,
  • 组和组权限,多对多,一个组可以赋予多个权限,一个权限可以赋给多个组
  • 用户和用户权限,多对多,一个用户可以有多个权限,一个权限可以赋给多个用户。

权限设置的2条路径

  • 用户设置所属组,通过组间接获得权限
  • 用户直接设置权限,auth_user_user_permissions

下图是auth_permission和django_content_type表关系,一对多关系。一个Model对应4个默认权限。

image

userprofile 就是user应用下的Model类UserProfile,一个模型类默认就有了4种权限

  • add增
  • delete删
  • change改
  • view查

也就是某个用户应该可以使用某个Model的某些权限。

那么用户是怎样拥有了权限?

class AbstractUser(AbstractBaseUser, PermissionsMixin):
    pass
class PermissionsMixin(models.Model): # 增加对组、权限的支持
    is_superuser = models.BooleanField()
    groups = models.ManyToManyField(Group, verbose_name=_('groups'))
    user_permissions = models.ManyToManyField(Permission, 
verbose_name=_('user permissions'))
    
    def get_user_permissions(self, obj=None): # 获取用户直接的权限
        pass
    def get_group_permissions(self, obj=None): # 获取用户通过组获取的权限
        pass
    def get_all_permissions(self, obj=None): # 获取用户所有权限
        pass
    def has_perm(self, perm, obj=None):
        pass # 激活的超级用户永远返回True
    def has_perms(self, perm_list, obj=None):
        pass

PermissionMixin 同时提供了访问用户权限、组权限的方法。

  • 超级用户拥有所有权限,或者说无视权限限制。参看PermissionsMixin.has_perm
  • 普通用户,创建完,没有设置任何组、任何权限,就是什么权限都没有

AbstrauctUser 继承了PermissionsMixin,因此用户就拥有了权限,从代码中可以已看出

  • 用户权限user_permissions、组groups都是多对多关系
  • 用户对象可以获取该用户直接权限get_user_permissions
  • 用户对象可以获得该用户组的权限get_group_permissions
  • 用户对象可以获得该用户所有权限get_all_permissions
  • 用户是否具有该权限has_perm
  • 用户是否具有该权限列表所有的权限has_perms

perm的格式是.

‘user.view_userprofile’ 权限

Django官方文档

Permissions can be set not only per type of object, but also per specific 
object instance. By using the has_view_permission(), has_add_permission(), 
has_change_permission() and has_delete_permission() methods provided by the 
ModelAdmin class, it is possible to customize permissions for different 
object instances of the same type.
User objects have two many-to-many fields: groups and user_permissions. User 
objects can access their related objects in the same way as any other Django 
model:

1 组权限设置
group.permissions.set([permission_list])
group.permissions.add(permission, permission, ...)
group.permissions.remove(permission, permission, ...)
group.permissions.clear()

2 关注用户和组(角色)的方法,项目中我们不直接给用户赋权,而是通过角色
myuser.groups.set([group_list])
myuser.groups.add(group, group, ...)
myuser.groups.remove(group, group, ...)
myuser.groups.clear()
下面是用户权限设置,我们不用
myuser.user_permissions.set([permission_list])
myuser.user_permissions.add(permission, permission, ...)
myuser.user_permissions.remove(permission, permission, ...)
myuser.user_permissions.clear()

创建分支

前后台代码中,都创建perm分之,开始新的开发

git checkout -b perm

权限管理

功能:

  • 权限列表、分页
  • 权限搜索

因为添加权限是Django对模块自动增加的,所以不需要提供增加权限功能,编辑、删除也不提供了,是只读的。

前台代码

src/router/index.js

import Perm from '../views/user/PermView'
const routes = [
 { path: '/', redirect: '/login' },
 { path: '/login', component: Login },
 {
    path: '/home',
    component: Home,
    redirect: '/welcome', // 访问/home重定向到/welcome,进入子路由
    children: [
     { path: '/welcome', component: Welcome },
     { path: '/users', component: User },
     { path: '/users/perms', component: Perm }
   ]
 }
]

src/views/user/PermView.vue