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验证时如何防止抓包盗用?

14 回复

一次请求换一个 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

核心要点:

  1. 并发控制flask-limiter1 per second限制是最直接的方法,实际效果就是阻止并发请求。如果需要严格单用户,可以结合用户会话或IP进行更精细控制。

  2. Token防盗用

    • 使用secrets.token_urlsafe()生成高熵token
    • 服务端存储token并设置短有效期(5分钟)
    • 强制HTTPS防止中间人抓包
    • 每次验证后更新token时间(可选防重放)
  3. 补充建议

    • 生产环境用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 更好了

回到顶部