文章目录
- 一、三大认证
- 1. 认证组件:校验用户
- 2. 权限组件:校验用户权限
- 3. 频率组件:限制视图接口被访问次数
- 4. 分析源码
- 二、权限六表
- 1. RBAC 认证
- 2. 权限三表
- 3. 权限五表
- 4. 权限六表
- 三、六表间访问
- 1. 分析源码
- 2. 六表间访问方法
- 3. 代码实现
- 4. 脚本化启动查看表
一、三大认证
1. 认证组件:校验用户
- 游客:无认证信息,校验通过,直接进入下一步权限认证校验
- 合法用户:带正确认证信息,校验通过,将用户存储在 request.user 中,再下一步权限认证校验
- 非法用户:带错误认证信息,校验失败,抛出异常,返回 403 权限异常结果
详细:Django REST 框架详解 08 | 认证组件
2. 权限组件:校验用户权限
- 必须登录
- 所有用户
- 登录读写,游客只读
- 自定义用户角色
认证通过:可以进入下一步校验(频率认证)
认证失败:抛出异常,返回 403
详细:Django REST 框架详解 09 | 权限组件
3. 频率组件:限制视图接口被访问次数
- 限制的条件:IP,userid,唯一键(如手机号)
- 频率周期时间:s,m,h,d
- 频率的次数:3/h
没有达到限次:正常访问
达到限次:限制时间内不能访问,返回500,限制时间达到后,可以重新访问
详细:Django REST 框架详解 10 | 频率认证组件
4. 分析源码
class APIView(View):def initial(self, request, *args, **kwargs):"""Runs anything that needs to occur prior to calling the method handler."""self.format_kwarg = self.get_format_suffix(**kwargs)neg = self.perform_content_negotiation(request)request.accepted_renderer, request.accepted_media_type = negversion, scheme = self.determine_version(request, *args, **kwargs)request.version, request.versioning_scheme = version, schemeself.perform_authentication(request)self.check_permissions(request)self.check_throttles(request)
二、权限六表
基于用户角色权限访问的控制 (RBAC,Role Based Access Control):Django 框架使用
基于 auth 认证:ThinkPHP 使用
1. RBAC 认证
RBAC 认证规则通常会分为 三表规则,五表规则,Django 采用六表规则
2. 权限三表
用户表,角色表,权限表
User
Group
id | name | p_id |
---|
1 | 校长 | 1 |
2 | 讲师 | 1,2,3 |
3 | 助教 | 1,3 |
Permission
3. 权限五表
会发现权限三表中,User 表与 Group 表多对多关系, Group 表与 Permission 表是多对多关系。所以,需要新建这两张的关系表,这就是权限五表。
用户表,角色表,权限表,用户角色关系表,角色权限关系表
U-G关系表
G-P关系表
id | g_id | p_id |
---|
1 | 1 | 1 |
2 | 2 | 1 |
3 | 2 | 2 |
4 | 2 | 3 |
5 | 3 | 1 |
6 | 3 | 3 |
User
Group
Permission
4. 权限六表
有的用户可能会执行角色分组以外的权限,所以除了五表外,多了用户表与权限表的关系表。
用户表,角色表,权限表,用户角色关系表,角色权限关系表,用户权限关系表。
U-P关系表
三、六表间访问
1. 分析源码
auth/models.py
class PermissionsMixin(models.Model):"""Add the fields and methods necessary to support the Group and Permissionmodels using the ModelBackend."""is_superuser = models.BooleanField(_('superuser status'),default=False,help_text=_('Designates that this user has all permissions without ''explicitly assigning them.'),)groups = models.ManyToManyField(Group,verbose_name=_('groups'),blank=True,help_text=_('The groups this user belongs to. A user will get all permissions ''granted to each of their groups.'),related_name="user_set",related_query_name="user",)user_permissions = models.ManyToManyField(Permission,verbose_name=_('user permissions'),blank=True,help_text=_('Specific permissions for this user.'),related_name="user_set",related_query_name="user",)
auth/models.py
class Group(models.Model):name = models.CharField(_('name'), max_length=150, unique=True)permissions = models.ManyToManyField(Permission,verbose_name=_('permissions'),blank=True,)
2. 六表间访问方法
用户表:访问角色 groups, 访问权限 user_permissions
角色表:访问用户 user_set, 访问权限 permissions
权限表:访问用户 user_set, 访问角色 group_set
3. 代码实现
自定义用户表 models.py
class User(AbstractUser):mobile = models.CharField(max_length=11, unique=True)class Meta:db_table = 'api_user',verbose_name = '用户表',verbose_name_plural = verbose_namedef __str__(self):return self.username
数据库迁移
python manage.py makemigrations
python manage.py migrrate
迁移报错解决
如果自定义 User 表后,在另一个项目中采用原生 User 表,完成数据库迁移时,可能会失败
解决:
- 卸载 Django 重新装
- 清空数据库迁移记录文件
django.contrib.admin.migraions 清空除了 init.py 以外的文件
django.contrib.auth.migraions 清空除了 init.py 以外的文件
创建成功后数据库表如下:
4. 脚本化启动查看表
import os, djangoos.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_proj02.settings')
django.setup()from api import models
user = models.User.objects.first()
print(user.username)
print(user.groups.first())
print(user.user_permissions.first().name)print("-"*20)
from django.contrib.auth.models import Group
group = Group.objects.first()
print(group.name)
print(group.user_set.first().username)
print(group.permissions.first().name)print("-"*20)
from django.contrib.auth.models import Permission
p_1 = Permission.objects.filter(pk=1).first()
print(p_1.user_set.first().username)
p_2 = Permission.objects.filter(pk=2).first()
print(p_2.group_set.first().name)