赞
踩
目录
django自带的有权限系统和组功能,对登录用户进行权限判断,下面举例说明模拟一个用户在购买VIP后就获得了上传和下载文件的权限了,能够使用上传和下载文件的功能。
在django创建数据库表时会默认创建用组和权限相关的表:
组的使用过程:获取用户对应的内容类型----创建权限----将权限分配到组----将用户加入到组
前提:需要用户先登录:参考之前的文章,注册账号,并调用登录接口,获取登录接口返回的token 在Django中使用PyJWT实现登录及验证功能-CSDN博客
- class AssignGroupPermissions(View):
- """用户购买VIP后,分配用户到相应的组里"""
- @method_decorator(decorator_login_require)
- def post(self, request):
- try:
- with transaction.atomic():
- save_id = transaction.savepoint()
- # 获取权限对应的内容类型
- content_type = ContentType.objects.get_for_model(request.user)
- # 创建一个名为VIP的用户组
- group, create = Group.objects.get_or_create(name="VIP")
-
- # 创建上传和下载的权限
- upload_permission, created = Permission.objects.get_or_create(
- codename='can_upload',
- name='Can Upload',
- content_type=content_type
- )
-
- download_permission, created = Permission.objects.get_or_create(
- codename='can_download',
- name='Can Download',
- content_type=content_type
- )
- # 将权限分配到用户组
- group.permissions.add(upload_permission, download_permission)
-
- # 将当前登录的用户加入到用户组中
- request.user.groups.add(group)
- except Exception as e:
- # 如果操作失败,回滚事务到保存点
- transaction.savepoint_rollback(save_id)
- return JsonResponse({"status": 400, "msg": f"用户权限分配失败: {str(e)}"})
- else:
- # 如果操作成功,提交事务
- transaction.savepoint_commit(save_id)
- return JsonResponse({'status': 200, 'msg': "用户权限分配成功"})
为视图AssignGroupPermissions配置url后,带着登录返回的token请求url,将会在表中创建权限及加入组等一系列操作:
到此组里有了上传和下载的权限,用户又添加到了组里,所以只要加入到组里的用户都有上传和下载的权限!
- def decorator_group_permission_require(func):
- """验证登录用户是否有VIP组的相应权限的装饰器"""
- def wrapper(request, *args, **kwargs):
- authorization = request.META.get('HTTP_AUTHORIZATION', '') # 获取Headers里的Authorization值
- if authorization:
- payload = parse_payload(authorization) # 解密token
- status = payload['status']
- if status:
- username = payload['data']['username']
- user = UserProfile.objects.filter(username=username).first() # 解密后查询
- if user:
- if user.groups.filter(name='VIP').exists():
- # 用户属于 VIP 用户组
- return func(request, *args, **kwargs)
- else:
- return JsonResponse({"status": 401, "msg": "没有VIP组权限"})
- else:
- return JsonResponse({"status": 401, "msg": payload['error']})
- return JsonResponse({"status": 401, "msg": "对不起,您还未登录"})
- return wrapper
- @method_decorator(decorator_group_permission_require, name='dispatch')
- class UploadDownloadView(View):
- """上传和下载视图"""
- def get(self, request):
- # 下载的逻辑
- return JsonResponse({"status": 200, "msg": "下载成功"})
-
- def post(self, request):
- # 上传的逻辑
- return JsonResponse({"status": 200, "msg": "上传成功"})
为视图UploadDownloadView配置url后,使用登录接口返回的token登录请求url,在请求前就会判断该登录的用户是否同时有上传和下载的权限访问该视图
使用有组权限的用户访问url测试
请求GET下载
请求POST上传
使用没有加入到组的其他用户登录时请求url时就报提示没有VIP组的权限
上面的权限是用户加入到某一个组里才能拥有组里的权限,现在是直接对某一个用户直接分配一个或多个权限,不再加入到组里
- class AssignPermissions(View):
- """ 用户购买VIP后,分配用户相应的权限"""
- @method_decorator(decorator_login_require)
- def post(self, request):
- try:
- with transaction.atomic():
- save_id = transaction.savepoint()
- # 获取用户对应的内容类型
- content_type = ContentType.objects.get_for_model(request.user)
-
- # 创建上传和下载的权限
- upload_permission, created = Permission.objects.get_or_create(
- codename='can_upload',
- name='Can Upload',
- content_type=content_type
- )
-
- download_permission, created = Permission.objects.get_or_create(
- codename='can_download',
- name='Can Download',
- content_type=content_type
- )
- # 给当前登录的用户分配上传和下载权限
- request.user.user_permissions.add(upload_permission, download_permission)
-
- except Exception as e:
- # 如果操作失败,回滚事务到保存点
- transaction.savepoint_rollback(save_id)
- return JsonResponse({"status": 400, "msg": f"用户权限分配失败: {str(e)}"})
- else:
- # 如果操作成功,提交事务
- transaction.savepoint_commit(save_id)
- return JsonResponse({'status': 200, 'msg': "用户权限分配成功"})
- def decorator_permission_require(func):
- """验证登录用户是否有上传和下载的权限的装饰器"""
- def wrapper(request, *args, **kwargs):
- authorization = request.META.get('HTTP_AUTHORIZATION', '') # 获取Headers里的Authorization值
- if authorization:
- payload = parse_payload(authorization) # 解密token
- status = payload['status']
- if status:
- username = payload['data']['username']
- user = UserProfile.objects.filter(username=username).first() # 解密后查询
- if user:
- if user.has_perm('users.can_upload') and not user.has_perm('users.can_download'):
- # 用户只有上传权限,没有下载权限
- if request.method == 'POST':
- return func(request, *args, **kwargs)
- else:
- return JsonResponse({"status": 401, "msg": "没有下载权限"})
- elif not user.has_perm('users.can_upload') and user.has_perm('users.can_download'):
- # 用户没有上传权限,只有下载权限
- if request.method == 'GET':
- return func(request, *args, **kwargs)
- else:
- return JsonResponse({"status": 401, "msg": "没有上传权限"})
- elif user.has_perm('users.can_upload') and user.has_perm('users.can_download'):
- # 用户同时拥有上传和下载的权限
- return func(request, *args, **kwargs)
- else:
- return JsonResponse({"status": 401, "msg": "没有上传和下载权限"})
- else:
- return JsonResponse({"status": 401, "msg": payload['error']})
- return JsonResponse({"status": 401, "msg": "对不起,您还未登录"})
- return wrapper
这里的装饰器对用户的权限进行更加详细的判断,分了为三种情况
- @method_decorator(decorator_permission_require, name='dispatch')
- class UploadDownloadView(View):
- """上传和下载视图"""
- def get(self, request):
- # 下载的逻辑
- return JsonResponse({"status": 200, "msg": "下载成功"})
-
- def post(self, request):
- # 上传的逻辑
- return JsonResponse({"status": 200, "msg": "上传成功"})
使用有权限的访问
有三种情况:
有下载没有上传权限
有上传没有下载权限
请求上传是成功的
没有任何权限
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。