模型类
# 用户表
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
用户表
角色表:
权限表:
角色---权限(多对多,公共表)