为什么需要restful形式的权限管理
最近在写flask应用时使用了 restful 形式的flask.views.MethodView,但是在对其进行权限管理时遇到了一些问题
flask文档上介绍说用
1decorators = []
添加装饰器,但实际使用上,比如
- get 和 post 采用不同的权限
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,就这样,可能还不完善或有一些问题,如有问题请联系我
知识共享署名-非商业性使用-相同方式共享4.0国际许可协议