最近在一個(gè)項(xiàng)目中,需要判斷 restful 接口函數(shù)傳入的時(shí)候屿笼,是否之前已經(jīng)登錄狀態(tài)是某個(gè)特定用戶牺荠,以及該用戶有沒有指定的權(quán)限。檢查下來如果沒有的話驴一,立刻返回錯(cuò)誤休雌,中斷功能。
遮掩的場(chǎng)景雖然也可以通過標(biāo)準(zhǔn)的調(diào)用函數(shù)來操作肝断,但都不如用裝飾器來得簡(jiǎn)單杈曲。都知道裝飾器好用不好寫,廢話不說胸懈,先來看看這個(gè)場(chǎng)景怎么實(shí)現(xiàn)担扑,還是有一定的通用性的。
def validate_current_is_admin(f):
@functools.wraps(f)
def decorated_function(*args, **kws):
# 需要在登錄狀態(tài)調(diào)用, 檢查是否為有admin權(quán)限的用戶登錄趣钱,
# 如果不是涌献,返回錯(cuò)誤碼;
if g.user.user_name != 'admin':
raise CustomFlaskErr(USER_MUST_HAS_ADMIN_PRIVILEGE, status_code=401)
# 驗(yàn)證權(quán)限是否為 admin, 不是的話首有,返回401錯(cuò)誤
if g.user.role_id != Permission.ADMIN:
raise CustomFlaskErr(USER_MUST_HAS_ADMIN_PRIVILEGE, status_code=401)
return f(*args, **kws)
return decorated_function
這是一個(gè)標(biāo)準(zhǔn)的裝飾器的寫法燕垃,如果你要寫一個(gè)簡(jiǎn)單的裝飾器枢劝,整個(gè)框架可以參考。
裝飾器調(diào)用舉例:
@app.route('/api/create_user', methods=['POST'])
@auth.login_required
@validate_current_is_admin
def create_user():
# 獲得參數(shù)
user_name = request.json.get('user_name')
password = request.json.get('password')
......
核心代碼的業(yè)務(wù)邏輯也不復(fù)雜卜壕,根據(jù) flask 的 g 對(duì)象中預(yù)存的用戶 user 進(jìn)行檢查處理呈野,flask 的這些定義非常靈活,flask.g
怎么使用可以查看 flask 的文檔印叁。
這里的user
以及相關(guān)的屬性屬于具體業(yè)務(wù)邏輯被冒,就不展開解釋了,可以望文生義轮蜕。
如果檢查下來不符合的話昨悼,會(huì)調(diào)用自定義的 flask 錯(cuò)誤,這部分內(nèi)容可以查看之前寫的 python flask 寫 api 如何返回自定義錯(cuò)誤跃洛。
因?yàn)椴粚?duì)args
和kws
這些參數(shù)進(jìn)行解析和處理率触,所處理的是 flask 全局對(duì)象。最后將參數(shù)都原路打包返回即可汇竭,沒有問題的話交給使用裝飾器的代碼繼續(xù)處理葱蝗。
這個(gè)例子比較簡(jiǎn)單,主要還是熟悉裝飾器的基本用法细燎。