[英]How to make a python decorator function in Flask with arguments (for authorization)
我在燒瓶登錄中使用了一個燒瓶片段來檢查用戶是否已登錄:
from functools import wraps
def logged_in(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if session.get('logged_in') is not None:
return f(*args, **kwargs)
else:
flash('Please log in first.', 'error')
return redirect(url_for('login'))
return decorated_function
我這樣裝飾視圖:
@app.route('/secrets', methods=['GET', 'POST'])
@logged_in
def secrets():
error = None
我也想為授權做類似的事情。 現在,我有很多觀點來檢查用戶是否擁有資源,讓我們說hotdogs
資源。
如果logged_in用戶是該特定熱狗的所有者,他可以編輯和管理他的熱狗。 如果他不是,我會把他踢到未經授權的屏幕。
@app.route('/<hotdog>/addmustard/',methods=["GET"])
@logged_in
def addmustard(hotdog):
if not (authorizeowner(hotdog)):
return redirect(url_for('unauthorized'))
do_stuff()
authorizeowner()
將熱狗作為輸入,並檢查記錄的熱狗所有者是否與會話變量中列出的所有者名稱匹配。
我嘗試制作一個類似於我登錄的owns_hotdog包裝器/裝飾器功能,但它抱怨它不接受參數。 我怎樣才能實現類似的東西呢? 就像是...
def owns_hotdog(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if not authorizeowner(hotdog):
return f(*args, **kwargs)
else:
flash('Please log in first.', 'error')
return redirect(url_for('login'))
return decorated_function
從錯誤消息中,裝飾器似乎沒有收到Flask視圖可以從路徑中的變量訪問的熱狗參數。 我的希望是......
@app.route('/<hotdog>/addmustard/',methods=["GET"])
@logged_in
@owns_hotdog(hotdog)
def addmustard(hotdog):
do_stuff()
一切都適用於我當前的authorizeowner(熱狗)功能,但是將它作為我的路線頂部的包裝器而不是作為路線內的第一行,這似乎更清晰。
其他一些說明:
這是怎么做的:
from functools import update_wrapper
def owns_hotdog(hotdog):
def decorator(fn):
def wrapped_function(*args, **kwargs):
# First check if user is authenticated.
if not logged_in():
return redirect(url_for('login'))
# For authorization error it is better to return status code 403
# and handle it in errorhandler separately, because the user could
# be already authenticated, but lack the privileges.
if not authorizeowner(hotdog):
abort(403)
return fn(*args, **kwargs)
return update_wrapper(wrapped_function, fn)
return decorator
@app.errorhandler(403)
def forbidden_403(exception):
return 'No hotdogs for you!', 403
當decorator接受參數時,它不是真正的裝飾器,而是返回真正裝飾器的工廠函數。
但如果我是你,我會使用Flask-Login進行身份驗證,並使用自定義裝飾器和函數來擴充它以處理授權。
我看了看Flask-Principal,但發現它的味道過於復雜。 沒有檢查Flask-Security,但我相信它使用Flask-Principal進行授權。 總的來說,我認為使用一些自定義代碼的Flask-Login足夠大部分時間。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.