代码之家  ›  专栏  ›  技术社区  ›  ravioli

django authorization-在函数调用中返回重定向

  •  0
  • ravioli  · 技术社区  · 6 年前

    我正在添加一些自定义授权,以验证已登录的用户是否可以访问我的应用程序的特定部分。虽然不漂亮,但很管用:

    view_permissions = {
        'admin_list': {
            'school':{'userrole':['S','A'], 'usertype':[]},
            'class':{'userrole':['S','A'], 'usertype':[]},
            ' ... '
        },
        'delete_object': { ... },
        'edit_object': { ... },
        }
    }
    
    def check_permissions(request, viewname, objecttype):
        if(request.user.userrole in view_permissions[viewname][objecttype]['userrole'] or 
           request.user.usertype in view_permissions[viewname][objecttype]['usertype']
        ):
            return True
        else:
            return False
    
    def delete_object(request, objecttype, objectid):
    
        # Redirect to home page if not authorized
        if(not check_permissions(request, 'delete_object', objecttype)):
            return redirect('wakemeup:index')
    
        # Otherwise, continue processing
        myobject.delete()
        ...
    
        return admin_list(request, objecttype)
    

    我想做的是移动 redirect 进入 check_permissions 函数,如下所示:

    def check_permissions(request, viewname, objecttype):
        if( <check permissions are valid> ):
            pass # Authorized: Do nothing and continue with caller view logic
        else:
            return redirect('wakemeup:index') # Unauthorized: redirect to home
    
    def delete_object(request, objecttype, objectid):
    
        # Redirect to home page if not authorized
        check_permissions(request, 'delete_object', objecttype))
    

    问题是,在 检查权限 函数不起作用。只有当我添加一个 return 调用逻辑:

    def delete_object(request, objecttype, objectid):
    
        # Redirect to home page if not authorized
        return check_permissions(request, 'delete_object', objecttype))
    

    我猜这与嵌套函数调用一直将其输出返回给原始调用方有关。但是有没有一个简单的方法可以让我从 检查权限 功能?

    编辑

    更新的函数——我必须访问 request 对象通过参数[0],但我可以通过 kwargs 是的。我想这是因为在表单中,请求对象只是在封面下传递,而不是作为参数传递。

    def check_perm(view):
        viewname = view.__name__
    
        def view_wrapper(*args, **kwargs):
    
            objecttype = kwargs['objecttype']
            myuser = args[0].user
    
            if not (
                myuser.userrole in view_permissions[viewname][objecttype]['userrole'] or 
                myuser.usertype in view_permissions[viewname][objecttype]['usertype']
            ):
                # Invalid permission - redirect
                return redirect('wakemeup:index')
    
            # Valid permission - continue
            return view(*args, **kwargs)
    
        return view_wrapper
    
    ...
    
    @check_perm
    def delete_object(request, objecttype, objectid):
      ...
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   Cole unutbu    6 年前

    我认为函数装饰器是解决这个问题的最佳方法。以下操作允许您检查条件(权限),必要时使用重定向劫持响应,如果不需要,则继续使用普通视图响应:

    from django.shortcuts import redirect
    
    def check_permissions(view):
        view_name = view.__name__
    
        def view_wrapper(*args, **kwargs):
            # Check permissions here.
            if False or False or True:
                # Hijack response with a redirect if conditions not met.
                return redirect('wakemeup:index')
    
            # Conditions met, continue with normal response.
            return view(*args, **kwargs)
    
        return view_wrapper
    
    @check_permissions
    def delete_object(request, object_type, object_id):
        # Your normal view...
        return
    

    另外,请注意它捕获视图名称的方式。在我看来更有活力。