Flask Security这个插件能对用户权限进行很好的控制。
经过三个model实现:
User,存放用户数据
Role,存放角色数据
User_Role.存放用户角色信息html
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
经过user_datastore能够查找用户,角色,以及赋予或者删除用户角色等操做。具体参见:http://pythonhosted.org/Flask-Security/api.htmlpython
好比咱们新建一个view:api
@app.route('/') @login_required def home(): return render_template('index.html')
这个要求登录,security会自动产生一个登录页面, 固然你也能够覆盖自带的template
若是填写正确就能够看到内容。
那么如何使用权限控制呢。app
@app.route('/dashboard') @roles_required('admin', 'editor') def dashboard(): return "dashboard"
这里使用了@roles_required()这个装饰器来实现,须要登录的用户拥有admin和editor两个角色。另一个相应的装饰器是@roles_accepted(),这个只要有其中一个角色就能够经过。
那么若是不知足条件,就会往其它地方跳转。
咱们看看其源代码:ui
def wrapper(fn): @wraps(fn) def decorated_view(*args, **kwargs): perms = [Permission(RoleNeed(role)) for role in roles] for perm in perms: if not perm.can(): if _security._unauthorized_callback: return _security._unauthorized_callback() else: return _get_unauthorized_view() return fn(*args, **kwargs) return decorated_view return wrapper
看到若是没有经过权限认证,那么就会查看是否有_unauthorized_callback这个方法。若是有就调用
若是没有,那么就会调用_get_unauthorized_view()方法。
而后继续看其代码:url
def _get_unauthorized_view(): cv = utils.get_url(utils.config_value('UNAUTHORIZED_VIEW')) utils.do_flash(*utils.get_message('UNAUTHORIZED')) return redirect(cv or request.referrer or '/')
能够看到其查找了'UNAUTHORIZED_VIEW'这个配置。
进入config_value,发现它调用了下面这个方法来查找配置:插件
def get_config(app): """Conveniently get the security configuration for the specified application without the annoying 'SECURITY_' prefix. :param app: The application to inspect """ items = app.config.items() prefix = 'SECURITY_' def strip_prefix(tup): return (tup[0].replace('SECURITY_', ''), tup[1]) return dict([strip_prefix(i) for i in items if i[0].startswith(prefix)])
要注意到,咱们在配置app的时候,要加一个‘SECURITY_’这个前缀才行!
因此只要咱们在app中配置:
app.config['SECURITY_UNAUTHORIZED_VIEW'] = '/unauth'
而后添加一个视图:code
@app.route('/unauth') def unauth(): return "unauth"
当认证失败后,就会跳转到这个页面了。htm
固然还有一个更灵活的配置方法,就是写一个装饰器,接受一个urlip
def set_unauth_view(url): def wrapper(fn): def decorator(*args, **kwargs): current_app.config['SECURITY_UNAUTHORIZED_VIEW'] = url return fn(*args, **kwargs) return decorator return wrapper
而后:
@app.route('/dashboard') @set_unauth_view('/unauth') @roles_required('admin', 'editor') def dashboard(): return "dashboard"
这样就能够针对特定的view指定跳转的页面了。