Django 權限管理


對於Django而言,雖然自帶了一些基本的通用權限限制,但現實中,可能我們更希望自己去定義業務權限划分

 

 

Django對於權限這塊的部分驗證方法

1 user = request.user
2 user.is_superuser  #是否是超級管理員
3 user.s_anonymous()  #是否匿名用戶,及未登錄用戶
4 user.groups.select_related()  #獲取用戶對應的組角色對象,
5 #當獲取到group后,通過group.name獲取組名,

 

下面是一段完整的權限控制例子

  1 #!/usr/bin/env python
  2 # encoding:utf8
  3 
  4 from django.core.urlresolvers import resolve
  5 from django.shortcuts import render
  6 
  7 
  8 # 定義角色權限
  9 roles = {
 10     'consultant': ['Customer', 'ConsultRecord'],
 11     'teachers': ['Course', 'ClassList', 'CourseRecord', 'StudyRecord'],
 12     'students':  ['StudyRecord'],
 13 }
 14 # 權限映射
 15 permission_map = {
 16     'view_home': ['index', 'GET', []],  # 展示對應對可操作對象
 17     'view_object': ['admin_controller', 'GET', ['show']],  # 查看具體對象對數據信息
 18     'edit_object': ['admin_controller', 'POST', ['show', 'id']],  # 具有編輯該對象對權限
 19     'add_object_view': ['admin_controller', 'GET', ['add']],  # 進入添加頁面,但不表示可以進行修改,該權限用於對表格顯示字段過長,顯示不全,可以進入該頁面查看
 20     'add_object': ['admin_controller', 'POST', ['add']],  # 具有添加該對象對權限
 21     'delete_object': ['admin_controller', 'POST', ['show', 'data']],  # 具有刪除該對象對權限
 22 }
 23 
 24 
 25 def check_process(*args, **kwargs):
 26     request = args[0]
 27     user = request.user
 28     if user.is_superuser:
 29         return True
 30     resolver_match_obj = resolve(request.path)
 31     url_name = resolver_match_obj.url_name
 32     args = list(resolver_match_obj.args)
 33     args.extend(request.GET)
 34     args.extend(request.POST)
 35     print('begin checking permission ', resolver_match_obj)
 36     if url_name:
 37         is_match = False
 38         match_perm = None
 39         for permission in permission_map:
 40             permission_action = permission_map[permission]  # 獲取url對應的權限動作
 41             print('----------------url action: ', permission_action)
 42             if len(permission_action) == 3:  # 為保障下面語句執行不為語法而被破壞,加上該條件,強制性判斷,否則放行
 43                 define_url_name, define_request_method, define_others = permission_action
 44                 if url_name == define_url_name:
 45                     print("match url name: ", define_url_name)
 46                     if request.method == define_request_method:
 47                         print("match method: ", define_request_method)
 48                         if define_others:  # 如果定義了具體參數匹配,則繼續匹配參數
 49                             print("check others: ", permission, define_others)
 50                             for arg in define_others:
 51                                 if hasattr(request, str(define_request_method)):
 52                                     request_method = getattr(request, str(define_request_method))  # 獲取對應的請求方法對象
 53                                     if hasattr(request_method, arg) or arg in args:  # 如果能匹配參數,則標記匹配
 54                                         is_match = True
 55                                         print("others match: ", arg)
 56                                     else:
 57                                         print("others not match: ", arg)
 58                                         is_match = False
 59                             if is_match:
 60                                 print("others match done: ", permission, permission_action)
 61                                 match_perm = permission
 62                                 break
 63                         else:
 64                             is_match = True
 65                             match_perm = permission
 66                             print("url check done ...", permission, permission_action)
 67                             break
 68             else:
 69                 print('please check the define rules, maybe has some problem')
 70                 return True  # 如果定義的動作不完整,為避免新增權限的缺陷影響業務,這種錯誤應該放行處理
 71     else:
 72         return True  # 如果沒有找到對應的url name則放行處理
 73 
 74     if is_match:
 75         print("begin check user permission ...")
 76         if user.is_anonymous():
 77             print("user has not login ...")
 78             return True  # 如果用戶是匿名,說明該頁面可能不需要權限控制,放行處理,假如該view需要登錄認證,那么再次權限處理時,不會在此處理
 79         elif user.has_perm('%s.%s' % (__package__, match_perm)):
 80             groups = user.groups.select_related()
 81             model_list = []
 82             for group in groups:
 83                 if group.name in roles:
 84                     model_list.extend(roles[group.name])
 85             if args and len(args) > 1:  # 如果URL獲取到參數,則對參數進行比較
 86                 access_model = args[0]
 87                 if access_model not in model_list:  # 該操作主要攔截,直接使用URL方式而非超鏈接,嘗試指定不同model訪問其它數據
 88                     return False
 89                 return True
 90             return model_list if model_list else True  # 如果model_list為空,且該用戶還有權限,那么只有超級用戶才有這種特權了
 91     return False
 92 
 93 
 94 def decorator(func):
 95     def wrapper(*args, **kwargs):
 96         check_result = check_process(*args, **kwargs)
 97         if not check_result:
 98             render_respond = render(args[0], '403.html')
 99             render_respond.status_code = 403  # 修改頭部信息狀態碼
100             print("permission refused ...")
101             return render_respond
102         if type(check_result) is list:  # 該參數僅在本次view中可能有用,所以在return時需要嘗試捕獲,如果出錯,則嘗試移除該key,再返回,再有其它錯誤,就可以排除是該權限控制產生的了
103             kwargs['model_list'] = check_result
104         print('permission check passed...')
105         try:
106             return func(*args, **kwargs)
107         except TypeError:
108             kwargs.pop('model_list')
109             return func(*args, **kwargs)
110     return wrapper

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM