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指定跳轉的頁面了。