简单实现的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)
本文来自博客园,作者:羊驼之歌,转载请注明原文链接:https://www.cnblogs.com/shijieli/p/19068734

浙公网安备 33010602011771号