Python中基于Flask的RESTful API如何限制并发用户数为1,使用Token验证时如何防止抓包盗用?
服务器端算是个应用服务器吧,Flask 搭了 RESTful API,PyQT 客户端调用 RESTful API 完成业务操作。但是卖给用户的话是按 1 个用户授权,如果用户登录后给个 Token 做以后 API 的授权的话,抓包或浏览器调试工具里找到 API 就可以无限制调用需要 Token 的 API 了,RESTful 是无状态的,一般客户公司里都一个公网 IP 出来的,有办法识别吗?还是用其它授权方案代替 Token ?
先谢过了。。
Python中基于Flask的RESTful API如何限制并发用户数为1,使用Token验证时如何防止抓包盗用?
一次请求换一个 Token
from flask import Flask, request, jsonify
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
import secrets
import time
app = Flask(__name__)
# 初始化限流器 - 关键配置:全局限制每秒1个请求
limiter = Limiter(
get_remote_address,
app=app,
default_limits=["1 per second"], # 核心限制:1秒1请求 = 并发≈1
storage_uri="memory://"
)
# 存储有效token和最后使用时间
valid_tokens = {}
TOKEN_TIMEOUT = 300 # token有效期5分钟
def generate_secure_token():
"""生成加密安全的token"""
return secrets.token_urlsafe(32)
def validate_token(token):
"""验证token并防止重放攻击"""
if token not in valid_tokens:
return False
# 检查token是否过期
if time.time() - valid_tokens[token] > TOKEN_TIMEOUT:
del valid_tokens[token]
return False
# 更新最后使用时间(可选,根据需求调整)
valid_tokens[token] = time.time()
return True
@app.route('/login', methods=['POST'])
def login():
"""登录接口获取token"""
# 这里应有实际用户验证逻辑
token = generate_secure_token()
valid_tokens[token] = time.time()
return jsonify({'token': token, 'expires_in': TOKEN_TIMEOUT})
@app.route('/api/protected', methods=['GET'])
@limiter.limit("1 per second") # 对具体接口加强限制
def protected_api():
"""受保护的API接口"""
token = request.headers.get('Authorization')
if not token or not validate_token(token):
return jsonify({'error': 'Invalid or expired token'}), 401
# 业务逻辑
return jsonify({'data': 'Sensitive operation completed'})
# 可选:HTTPS强制中间件
@app.before_request
def require_https():
if not request.is_secure:
return jsonify({'error': 'HTTPS required'}), 403
if __name__ == '__main__':
app.run(ssl_context='adhoc') # 测试用自签名HTTPS
核心要点:
-
并发控制:
flask-limiter的1 per second限制是最直接的方法,实际效果就是阻止并发请求。如果需要严格单用户,可以结合用户会话或IP进行更精细控制。 -
Token防盗用:
- 使用
secrets.token_urlsafe()生成高熵token - 服务端存储token并设置短有效期(5分钟)
- 强制HTTPS防止中间人抓包
- 每次验证后更新token时间(可选防重放)
- 使用
-
补充建议:
- 生产环境用Nginx限流更可靠
- 考虑添加请求签名(timestamp+nonce)
- 重要操作可加入二次验证
一句话建议:限流用flask-limiter,Token加HTTPS和短有效期。
https 应该抓不到吧
证书呀,就像银行登陆的证书
挺靠谱。做个状态机。
证书,请求签名
加个签名不就行了,token 参与签名。
首先,任何可以在用户机器上运行的代码都是可破解的,不管你如何限制多人访问,总是有办法可以绕过的。
一个比较简单粗暴的方案,提交的接口参数里面,增加一个加密过的 自增字段。 然后统计自增数字有冲突的情况,基本上,就可以知道哪个账号是有多开行为了的。
试过这种方案, 不行, 网络抖动一些就隔屁了.
改成按 API 调用次数收费。:doge:
讲正经的。
使用 jwt 来解决,在 jwt 存放用户名,token 和一个随机值(比如 uuid ),服务端保存下发的 jwt,推荐 redis。
jwt 过期时间设定要小一些,比如 1 分钟,甚至 30 秒,如果网络不稳定可以适当延长有效时间。
API 发现 JWT 过期时,重新生成一个 JWT 返回即可,同样服务端要保存。
这里 jwt 和鉴权 token 可以没有关联(取决于你的业务),jwt 可以过期,但必须是有合法签名,如果业务允许,你仍然可以让他继续。
如果使用抓包的方式获取 jwt 和 token,然后多处使用,那么在这个 jwt 过期后必然会产生,一个用户有多个不同的 jwt 同时有效的情况。
使用 SSL pinning 技术增大抓包难度。
自增字段、加密网卡号等方式都可以增加破解难度。
破解难度高到一定程度即可,再费劲就得不偿失了。
所以好些软件绑死 mac…
如果客户知道你 API 协议的细节,就可以搭建 API 中心,所有的客户端调用接口,都不是直接调用你的服务器接口,而是调用 API 中心的接口,API 中心对数据进行签名,使用队列一个一个地请求。你在服务器端没有任何办法可以知道,真正使用你服务的是谁。
你能做的,只有尽可能让你的 API 不会被挖出来了。
做头部数据的 hash ? hash 不一致就无效了,https 更好了

