在使用Flask實現Restful接口時,需要對請求參數進行校驗以判斷其是否符合特定的規則。本文將介紹如何通過
pre-request
庫優化校驗邏輯。
接口需求
假設我們需要實現一個收集用戶填寫的個人信息的接口,該接口的具體需求如下:
- 接口路徑:
/user/info/new
- 接口字段:
字段 | 類型 | 說明 |
---|---|---|
userName | string | 用戶昵稱,必填,2-20位字符串 |
gender | int | 用戶性別,必填,1-男 2-女 |
age | int | 用戶年齡,必填,18-60之間的整數 |
country | string | 用戶國籍,選填,默認為 中國 , 字符串長度為>2 |
接口實現
如果不借助任何第三方工具實現上述接口的話,代碼可能如下所示:
from flask import request, Flask
app = Flask(__name__)
@app.route("/user/info/new", methods=["POST"])
def user_info_handler():
# 1.判斷用戶名稱參數是否合法
user_name = request.form.get("userName")
if not user_name or not isinstance(user_name, str):
return "請填寫正確的用戶名稱"
if len(user_name) < 2 or len(user_name) > 20:
return "用戶名稱長度不正確"
# 2.判斷用戶性別參數是否合法
gender = request.form.get("gender")
if not gender:
return "請填寫用戶性別"
try:
gender = int(gender)
except ValueError:
return "用戶性別格式不正確"
if gender not in [1, 2]:
return "用戶性別參數必須在[1, 2]之間"
# 3.判斷用戶年級參數是否合法
age = request.form.get("age")
if not age:
return "請填寫用戶年齡"
try:
age = int(age)
except ValueError:
return "用戶年齡格式不正確"
if age < 18 or age > 60:
return "年齡必須在18-60之間"
# 4.判斷國籍是否合法
country = request.form.get("country", "中國")
country = str(country)
if len(country) < 2:
return "國籍名稱長度不合法"
# TODO: 用戶信息注冊邏輯
return "Success"
if __name__ == "__main__":
app.run(port=8080)
正如上面的代碼所示,為了保證存儲到數據庫中的數據符合設計要求,開發人員需要對入參做大量的校驗工作,稍有不慎就有可能為系統留下漏洞隱患。
使用 pre-request
校驗入參
同樣是實現上述的接口需求,我們來看一下通過pre-request
如何將大量重復的校驗邏輯進行屏蔽。
from flask import Flask
from pre_request import pre, Rule
app = Flask(__name__)
rule = {
"userName": Rule(type=str, required=True, gte=3, lte=20, dest="user_name"),
"gender": Rule(type=int, required=True, enum=[1, 2]),
"age": Rule(type=int, required=True, gte=18, lte=60),
"country": Rule(type=str, required=False, gte=2, default="中國")
}
@app.route("/user/info/new", methods=["POST"])
def user_info_handler():
params = pre.parse(rule=rule)
# TODO: 用戶信息注冊邏輯
return "Success"
if __name__ == "__main__":
app.run(port=8080)
如上方所示,復雜的參數校驗工作變成了校驗規則的編寫,pre.parse
函數會自動捕獲請求參數并判斷是否符合校驗規則,不符合校驗規則時會自動生成錯誤響應,用戶不需要做任何處理。