[Flask Security]當不能通過認證的時候制定跳轉
Flask Security這個插件能對用戶權限進行很好的控制。
通過三個model實現:
User,存放用戶數據
Role,存放角色數據
User_Role.存放用戶角色信息
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
通過user_datastore可以查找用戶,角色,以及賦予或者刪除用戶角色等操作。具體參見:http://pythonhosted.org/Flask-Security/api.html
比如我們新建一個view:
@app.route('/') @login_required def home(): return render_template('index.html')
這個要求登陸,security會自動產生一個登陸頁面, 當然你也可以覆蓋自帶的template
如果填寫正確就可以看到內容。
那么如何使用權限控制呢。
@app.route('/dashboard') @roles_required('admin', 'editor') def dashboard(): return "dashboard"
這里使用了@roles_required()這個裝飾器來實現,需要登陸的用戶擁有admin和editor兩個角色。另外一個相應的裝飾器是@roles_accepted(),這個只要有其中一個角色就可以通過。
那么如果不滿足條件,就會往其它地方跳轉。
我們看看其源代碼:
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()方法。
然后繼續看其代碼:
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'
然后添加一個視圖:
@app.route('/unauth') def unauth(): return "unauth"
當認證失敗后,就會跳轉到這個頁面了。
當然還有一個更靈活的配置方法,就是寫一個裝飾器,接受一個url
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指定跳轉的頁面了。
