Python中如何在服务器上拦截请求?

想实现的是: 服务器上安装的是 Nginx 或 Apache 提供 web 服务,我想在服务器上执行一个 Python 的脚本拦截用户请求的 Http 数据包。然后修改在发给容器,容器在返回给客户。请问大佬们 Python 可以实现吗?


Python中如何在服务器上拦截请求?
9 回复

可以,就是个反向代理


在服务器端拦截请求,通常指的是在请求到达核心业务逻辑前,进行预处理、过滤或修改。这可以通过中间件(Middleware)或装饰器(Decorator)来实现,具体取决于你使用的Web框架。

1. 使用装饰器(适用于函数视图) 装饰器是最直接的方式,适合在单个视图函数或方法前添加拦截逻辑。

from functools import wraps
from flask import Flask, request, jsonify

app = Flask(__name__)

def intercept_request(f):
    """拦截请求的装饰器"""
    @wraps(f)
    def decorated_function(*args, **kwargs):
        # 在这里编写你的拦截逻辑
        # 例如:检查请求头、验证权限、记录日志、修改请求数据等
        print(f"拦截到请求: {request.method} {request.url}")
        print(f"请求头: {dict(request.headers)}")
        print(f"请求参数: {request.args.to_dict()}")
        
        # 你可以选择继续处理请求,或直接返回响应来中断
        # 例如,如果缺少某个必要头,可以在此处返回错误
        # if 'X-API-Key' not in request.headers:
        #     return jsonify({'error': 'Missing API key'}), 401
        
        # 继续执行被装饰的视图函数
        return f(*args, **kwargs)
    return decorated_function

@app.route('/api/data', methods=['GET'])
@intercept_request  # 应用拦截装饰器
def get_data():
    return jsonify({'message': 'Hello from the API!'})

if __name__ == '__main__':
    app.run(debug=True)

2. 使用中间件(适用于全局或模块化拦截) 中间件在请求-响应周期中运行,可以拦截所有或一组请求。以下是使用FlaskWSGI中间件的例子。

from flask import Flask, request, jsonify

class RequestInterceptor:
    """一个简单的WSGI中间件,用于拦截所有请求"""
    def __init__(self, app):
        self.app = app

    def __call__(self, environ, start_response):
        # 在请求被Flask应用处理之前
        # environ包含请求的WSGI环境信息
        request_method = environ.get('REQUEST_METHOD')
        path_info = environ.get('PATH_INFO')
        print(f"[Middleware] 拦截请求: {request_method} {path_info}")

        # 你可以在这里修改environ(即请求信息)
        # 例如,添加自定义的头或参数
        # environ['HTTP_X_CUSTOM_HEADER'] = 'Intercepted'

        # 继续传递请求给Flask应用
        return self.app(environ, start_response)

app = Flask(__name__)
# 用我们的中间件包装Flask应用
app.wsgi_app = RequestInterceptor(app.wsgi_app)

@app.route('/')
def home():
    return jsonify({'status': 'ok'})

if __name__ == '__main__':
    app.run()

3. 在 Django 中使用中间件 如果你用的是Django,框架本身提供了强大的中间件系统。

# 在某个app的middleware.py文件中
class CustomInterceptorMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # 视图被调用之前的代码(拦截请求)
        print(f"Django拦截请求: {request.method} {request.path}")
        # 可以在这里访问和修改request对象
        # request.custom_attribute = 'some value'

        response = self.get_response(request) # 继续处理请求

        # 视图被调用之后的代码(拦截响应)
        return response

然后在settings.pyMIDDLEWARE列表中添加这个中间件的路径。

总结 用装饰器针对特定视图,用中间件进行全局处理。

  1. 用你的 Python 脚本替换 Nginx
    2. Nginx 到你的 Python 脚本,你的脚本再到后端服务
    3. 如果不能动 Nginx 可以用 iptables 实现 1

做个代理服务倒是可以,想不侵入的拦截是不容易实现的。

用 mitmproxy

性能很感人,最好先评估一下流量

用 verynginx 试试?需求不是特别复杂的话,也许并不需要 python。。。

你需要 nginx-lua

回到顶部