簡單實現的flask 帶限頻的apikey簽發續簽的demo
pip install flask flask-limiter
import time from flask import Flask, request, jsonify from flask_limiter import Limiter from flask_limiter.util import get_remote_address from functools import wraps app = Flask(__name__) limiter = Limiter( app=app, key_func=get_remote_address, default_limits=["100 per day", "10 per hour"] # 全局默認限頻規則 ) # 模擬存儲token, 真的用的話用mysql存儲然后關系字段自己隨便設計吧, 這里僅僅用一個用戶名和過期, 這里用戶名是為了標示一下信息, 萬一有人泄露了方便查, 或者禁用 VALID_API_KEYS = { "token名字用對稱加密進行生成一串隨機字符": ["比如這里放用戶名", "這放這token的過期時間戳"], # 比如如下的模擬數據 "db27ca0ff08ce7519bbc45dd93ef2e4c488a279d55d7dd2612b7edd11586264e5f75f279b227c8819f8e409079ca4b89": ["羊駝", time.time() + 3600], } def require_apikey(view_func): """驗證token的自定義裝飾器""" @wraps(view_func) def decorated_function(*args, **kwargs): # 從請求頭中獲取APIKey token = request.headers.get('X-API-KEY') if token and token in VALID_API_KEYS and time.time() < VALID_API_KEYS[token][1]: return view_func(*args, **kwargs) else: return jsonify({"error": "老兄你憑證呢?!"}), 401 return decorated_function # 創建token @app.route('/create_token') def create_token(): global VALID_API_KEYS # 模擬生成一個token記錄, 過期時間為1小時 token_string = f"token_{time.time()}" exp_time = time.time() + 3600 VALID_API_KEYS[token_string] = ["隨便寫個名字吧", exp_time] return jsonify({"status": "success", "message": "", "data": { "token": token_string, "exp": exp_time, }}) # 續簽token @app.route('/renew_token') @require_apikey def renew_token(): token_string = request.headers.get('X-API-KEY') global VALID_API_KEYS exp_time = time.time() + 3600 if VALID_API_KEYS.get(token_string): VALID_API_KEYS[token_string][1] = exp_time # 更細時間為往后一小時 return jsonify({"status": "success", "message": "", "data": { "token": token_string, "exp": exp_time, }}) @app.route('/by_5_per_minute') @limiter.limit("5 per minute") # 對此端點單獨設置限頻:每分鐘5次 @require_apikey # 需要有效的APIKey def protected_route(): return jsonify({"status": "success", "message": "", "data": "hello~~~(by_5_per_minute)"}) @app.route('/hello') def unprotected_route(): return jsonify({"status": "success", "message": "", "data": "hello~~~"}) @app.route('/by_1_per_second') @require_apikey @limiter.limit("1 per second") # 非常嚴格的限頻:每秒1次 def status_check(): return jsonify({"status": "success", "message": "", "data": "hello~~~(by_1_per_second)"}) if __name__ == '__main__': app.run(debug=True)
本文來自博客園,作者:羊駝之歌,轉載請注明原文鏈接:http://www.rzrgm.cn/shijieli/p/19068734

浙公網安備 33010602011771號