基于restful的flask权限管理


为什么需要restful形式的权限管理

最近在写flask应用时使用了 restful 形式的flask.views.MethodView,但是在对其进行权限管理时遇到了一些问题

flask文档上介绍说用

1decorators = []

添加装饰器,但实际使用上,比如

  • getpost 采用不同的权限

get 不使用 login_required
post 需要 login_required

这样就不能使用 decorators 对视图进行装饰

  • post ,delete, put 都需要 login_required,但是get不需要 而 delete 又需要更高级别的权限,我们可以这样

     1class AAA(MethodView):
     2
     3    def get(self,uid):
     4        ...
     5
     6    @login_required
     7    def post(self):
     8        ...
     9
    10    @login_required
    11    def put(self,uid):
    12        ...
    13
    14    @login_required
    15    @more_required
    16    def delete(self,uid):
    17        ...
    

    是不是看起来还不错, 但是,如果再加上类似EditBlogPostPermission 这样的权限管理呢? 是不是还需要这样

    1@login_required
    2def put(self,uid):
    3    permission = EditBlogPostPermission(uid)
    4    if permission.can():
    5        # Save the edits ...
    6        return render_template('edit_post.html')
    7    ...
    

    先不论样式丑不丑,最重要的代码的 可维护性 极差,所以我增加了如下代码

怎么实现restful形式的权限管理

同样采用装饰器实现,调用 BasePermission 时会自动调用 call 函数

 1class BasePermission(object):
 2
 3    def __call__(self, func):
 4        @wraps(func)
 5        def decorator(*args, **kwargs):
 6            meth = getattr(self, request.method.lower(), None)
 7            if meth is None and request.method == 'HEAD':
 8                meth = getattr(self, 'get', None)
 9            assert meth is not None, 'Unimplemented method %r' % request.method
10            check = meth(*args, **kwargs)
11            if check:
12                return check
13            else:
14                pass
15            return func(*args, **kwargs)
16
17        return decorator

举个例子,get方式不需要用户登陆,而其它方式需要,并且put方式需要创建主题的作者才能更改

 1class TopicPermission(BasePermission):
 2    @login_required
 3    def post(self):
 4        pass
 5
 6    def get(self, uid):
 7        pass
 8
 9    @login_required
10    def put(self, uid):
11        permission = EditTopicPermission(uid)
12        if not permission.can():
13            flash('')
14            return redirect(url_for('topic.topic', uid=uid))
15
16    @login_required
17    def delete(self,uid):
18        pass
19
20topic_permission = TopicPermission()

假设四种方式都需要同一种权限,都需要用户登陆,总不能每个函数前都加上装饰器吧 所以稍加修改

1decorators = ()
2def __call__(self, func):
3    if self.decorators:
4        for dec in self.decorators:
5            return dec(func)

OK,这样就可以添加

1decorators = [login_required]

来实现四种请求方式采用同一种权限

最后,你就可以在 AAA 这个类里添加

1decorators = [topic_permission]

实现restful形式的权限管理

ok,就这样,可能还不完善或有一些问题,如有问题请联系我

作者: honmaple
链接: https://honmaple.me/articles/2016/06/基于restful的flask权限管理.html
版权: CC BY-NC-SA 4.0 知识共享署名-非商业性使用-相同方式共享4.0国际许可协议
wechat
alipay

加载评论