杰瑞科技汇

Flask如何限制或记录IP访问?

  1. 开发环境:在本地开发时,希望从同一局域网内的其他设备(如手机、平板、另一台电脑)访问你的 Flask 应用。
  2. 生产环境:将 Flask 应用部署到服务器上,并配置防火墙或 Nginx 来限制只有特定 IP 地址才能访问。

下面我将详细讲解这两种场景下的具体操作。

Flask如何限制或记录IP访问?-图1
(图片来源网络,侵删)

开发环境 - 让局域网内的设备访问

默认情况下,Flask 的开发服务器 (flask run) 只监听 0.0.1 (localhost),这阻止了局域网内其他设备的访问,要让其他设备能访问,你需要告诉服务器监听所有可用的网络接口(0.0.0)。

方法 1:使用命令行参数(推荐)

这是最简单直接的方法,在运行 flask run 时,添加 --host=0.0.0.0 参数。

# 假设你的应用在 app.py 文件中
export FLASK_APP=app.py
flask run --host=0.0.0.0

输出示例:

 * Serving Flask app 'app'
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:5000
 * Running on http://192.168.1.10:5000  <-- 这就是你的局域网IP
Press CTRL+C to quit
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: ...

你可以在同一局域网内的其他设备上,用你电脑的局域网 IP 地址(如 http://192.168.1.10:5000)来访问了。

Flask如何限制或记录IP访问?-图2
(图片来源网络,侵删)

方法 2:在代码中配置

如果你不想每次都输入命令行参数,也可以在 Flask 应用初始化时配置 host

# app.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
    return 'Hello from a LAN device!'
# 如果你想在运行时直接指定host,可以使用下面的方式
if __name__ == '__main__':
    # '0.0.0.0' 表示监听所有可用的网络接口
    app.run(host='0.0.0.0', port=5000, debug=True)

然后直接运行 python app.py 即可。


生产环境 - 基于IP的访问控制

在生产环境中,直接使用 Flask 自带的服务器是不推荐的,因为它性能低下且不安全,你应该使用一个专业的 WSGI 服务器(如 Gunicorn、uWSGI)和一个反向代理(如 Nginx),IP 访问控制通常在 Nginx 或 WSGI 服务器层面实现。

方法 1:使用 Nginx 进行 IP 访问控制(推荐)

Nginx 是一个非常强大的反向代理,可以轻松实现基于 IP 的访问限制,这是最常见和推荐的做法。

Flask如何限制或记录IP访问?-图3
(图片来源网络,侵删)

步骤:

  1. 安装 Nginx

    # Ubuntu/Debian
    sudo apt update
    sudo apt install nginx
    # CentOS/RHEL
    sudo yum install nginx
  2. 配置 Nginx: 编辑你的 Nginx 配置文件,通常位于 /etc/nginx/sites-available//etc/nginx/conf.d/ 目录下,创建一个新文件,my_flask_app.conf

    # /etc/nginx/sites-available/my_flask_app.conf
    server {
        listen 80;
        server_name your_domain.com; # 或者你的服务器IP
        # --- 关键部分:IP 访问限制 ---
        # 只允许以下两个IP地址访问
        allow 123.45.67.89;   # 允许的IP 1
        allow 98.76.54.32;   # 允许的IP 2
        # 拒绝所有其他IP
        deny all;
        # --- IP 限制结束 ---
        location / {
            # 将请求代理到你的Flask应用(假设Gunicorn运行在8000端口)
            proxy_pass http://127.0.0.1:8000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
  3. 启用配置并重启 Nginx

    # 创建软链接以启用站点 (适用于 Debian/Ubuntu)
    sudo ln -s /etc/nginx/sites-available/my_flask_app.conf /etc/nginx/sites-enabled/
    # 检查配置语法是否正确
    sudo nginx -t
    # 如果没问题,重启 Nginx
    sudo systemctl restart nginx

只有你指定的 IP 地址 (45.67.8976.54.32) 才能访问你的应用,所有其他 IP 都会收到 403 Forbidden 错误。

方法 2:在 Flask 应用代码中进行 IP 检查

如果你不想使用 Nginx,或者你的逻辑非常复杂,必须在 Python 层面处理,你可以在 Flask 的请求钩子 中进行 IP 检查。

示例:

# app.py
from flask import Flask, request, abort
app = Flask(__name__)
# 定义一个允许访问的IP列表
ALLOWED_IPS = {'123.45.67.89', '98.76.54.32'}
@app.before_request
def limit_ip_access():
    # 获取客户端的真实IP地址
    # 如果使用了Nginx等反向代理,需要从 'X-Forwarded-For' 头部获取
    # 否则直接使用 request.remote_addr
    client_ip = request.headers.get('X-Forwarded-For', request.remote_addr).split(',')[0].strip()
    if client_ip not in ALLOWED_IPS:
        # 如果IP不在允许列表中,返回403错误
        abort(403, description="Forbidden: Your IP is not allowed to access this resource.")
@app.route('/')
def hello_world():
    # 只有通过了IP检查的请求才能到达这里
    return 'Hello from an allowed IP!'
if __name__ == '__main__':
    # 注意:生产环境请勿使用 app.run(),请使用 Gunicorn/uWSGI
    app.run(host='0.0.0.0', port=5000, debug=True)

注意事项:

  • 性能:这种方法会在每个请求到达视图函数之前都执行一次 IP 检查,对于高并发应用,可能会有轻微的性能开销,Nginx 的处理是在 C 语言层面,效率更高。
  • 获取真实IP:如果你的应用部署在 Nginx 后面,request.remote_addr 获取到的是 Nginx 服务器的 IP,你必须配置 Nginx 将客户端的真实 IP 通过 X-Forwarded-For 头部传递给 Flask,如上面的 Nginx 配置所示。
  • 推荐度不推荐作为唯一的访问控制手段,它更适合作为 Nginx 控制的一个补充,或者用于处理一些非常动态的、基于数据库的 IP 白名单/黑名单逻辑。

总结与最佳实践

场景 推荐方法 优点 缺点
开发环境 flask run --host=0.0.0.0 简单、快速、无需额外配置 仅适用于开发
生产环境 (IP限制) Nginx 的 allow/deny 指令 性能高、配置灵活、是行业标准 需要额外配置 Nginx
生产环境 (备用方案) Flask @app.before_request 钩子 逻辑灵活,可在Python代码中处理 性能相对较低,配置不当易出错

核心建议:

  • 开发时:直接用 --host=0.0.0.0 参数。
  • 部署时优先使用 Nginx 进行 IP 访问控制,这是最专业、最高效的做法,将 Nginx 作为你的第一道防线,处理静态文件、反向代理和访问控制,如果确实需要在 Python 层面做更复杂的逻辑,再考虑使用 Flask 的请求钩子作为补充。
分享:
扫描分享到社交APP
上一篇
下一篇