You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flask+SQLAlchemy中安全连接PostgreSQL,避免敏感信息泄露

安全配置SQLAlchemy数据库连接的方案

针对自行托管服务器的场景,以下几种方式既能保证敏感信息不泄露,又能流畅适配Windows开发和Linux部署:

1. 利用操作系统级安全存储读取凭据

直接将数据库敏感信息存储在操作系统的安全凭据管理器中,而非明文环境变量或配置文件,应用启动时通过专门的库读取。

适配方式:

  • Windows:使用Windows Credential Manager存储凭据,用keyring库读取
  • Linux:使用GNOME Keyring或KDE Wallet(系统默认的秘密服务),同样用keyring库读取

代码实现:

首先安装依赖:

pip install keyring

修改config.py,不再直接读环境变量,而是从系统凭据存储读取:

import keyring
from sqlalchemy.engine.url import URL

class ProductionConfig:
    # 从系统凭据存储获取数据库信息
    DB_USER = keyring.get_password("flask_app_db", "db_user")
    DB_PASS = keyring.get_password("flask_app_db", "db_pass")
    DB_HOST = keyring.get_password("flask_app_db", "db_host")
    DB_PORT = keyring.get_password("flask_app_db", "db_port")
    DB_NAME = keyring.get_password("flask_app_db", "db_name")

    # 构建SQLAlchemy连接字符串
    SQLALCHEMY_DATABASE_URI = URL.create(
        "postgresql+psycopg2",
        username=DB_USER,
        password=DB_PASS,
        host=DB_HOST,
        port=DB_PORT,
        database=DB_NAME
    )
    SQLALCHEMY_TRACK_MODIFICATIONS = False

凭据存储操作:

  • Windows(PowerShell):
# 添加凭据到Windows Credential Manager
cmdkey /generic:flask_app_db/db_user /user:your_db_username /pass:your_db_password
cmdkey /generic:flask_app_db/db_pass /user:your_db_username /pass:your_db_password
# 同理添加db_host、db_port、db_name
  • Linux(终端):
# 使用keyring命令行工具添加(先安装python-keyring-cli)
pip install keyring-cli
keyring set flask_app_db db_user
keyring set flask_app_db db_pass
# 依次设置其他字段

2. 加密的本地配置文件

将数据库连接信息加密存储在本地文件中,应用启动时使用密钥解密读取,密钥可通过操作系统环境变量传递(仅传递解密密钥,而非数据库凭据)。

实现步骤:

  1. 安装加密依赖:
pip install cryptography
  1. 编写加密脚本(一次性生成加密配置文件):
from cryptography.fernet import Fernet
import json

# 生成密钥(仅需一次,保存到安全位置,部署时通过环境变量传递)
key = Fernet.generate_key()
with open("secret.key", "wb") as f:
    f.write(key)

# 明文配置信息
db_config = {
    "DB_USER": "your_db_user",
    "DB_PASS": "your_db_pass",
    "DB_HOST": "your_db_host",
    "DB_PORT": "5432",
    "DB_NAME": "your_db_name"
}

# 加密配置
fernet = Fernet(key)
encrypted_config = fernet.encrypt(json.dumps(db_config).encode())
with open("encrypted_config.bin", "wb") as f:
    f.write(encrypted_config)
  1. 修改config.py读取加密文件:
from cryptography.fernet import Fernet
import json
import os

class ProductionConfig:
    # 从环境变量获取解密密钥(仅这个密钥暴露在环境变量,风险远低于数据库凭据)
    ENCRYPTION_KEY = os.environ.get("FLASK_DB_ENCRYPTION_KEY")
    if not ENCRYPTION_KEY:
        raise ValueError("FLASK_DB_ENCRYPTION_KEY environment variable not set")
    
    # 读取并解密配置
    fernet = Fernet(ENCRYPTION_KEY.encode())
    with open("encrypted_config.bin", "rb") as f:
        encrypted_config = f.read()
    db_config = json.loads(fernet.decrypt(encrypted_config).decode())

    SQLALCHEMY_DATABASE_URI = f"postgresql+psycopg2://{db_config['DB_USER']}:{db_config['DB_PASS']}@{db_config['DB_HOST']}:{db_config['DB_PORT']}/{db_config['DB_NAME']}"
    SQLALCHEMY_TRACK_MODIFICATIONS = False

部署注意:

  • 加密密钥secret.key仅在生成加密配置时使用,部署时将密钥值设置为Linux/Windows的环境变量(Linux通过export FLASK_DB_ENCRYPTION_KEY="xxx",Windows通过set FLASK_DB_ENCRYPTION_KEY=xxx)
  • encrypted_config.bin可随应用代码部署,因为没有密钥无法解密

3. PostgreSQL操作系统认证(无密码连接)

如果应用运行的操作系统用户与PostgreSQL数据库用户同名,可启用PostgreSQL的peer认证(Linux)或SSPI认证(Windows),无需存储任何密码,直接通过操作系统身份验证连接数据库。

配置步骤:

  1. PostgreSQL端配置:
    修改pg_hba.conf文件(Linux通常在/var/lib/postgresql/<version>/main/pg_hba.conf,Windows在C:\Program Files\PostgreSQL\<version>\data\pg_hba.conf),添加或修改对应规则:

    • Linux:
    local   your_db_name   your_db_user   peer
    host    your_db_name   your_db_user   127.0.0.1/32   scram-sha-256  # 远程连接仍用密码,本地用peer
    
    • Windows:
    local   your_db_name   your_db_user   sspi
    host    your_db_name   your_db_user   127.0.0.1/32   scram-sha-256
    

    修改后重启PostgreSQL服务。

  2. 应用端配置:
    修改config.py,连接字符串无需密码:

    class ProductionConfig:
        SQLALCHEMY_DATABASE_URI = "postgresql+psycopg2:///your_db_name"  # 本地连接,自动使用操作系统用户
        # 如果是远程连接且用SSPI/peer(仅信任局域网),可写:
        # SQLALCHEMY_DATABASE_URI = "postgresql+psycopg2://@your_db_host/your_db_name"
        SQLALCHEMY_TRACK_MODIFICATIONS = False
    

优势:

完全避免存储密码,安全性最高,仅需确保操作系统用户权限严格控制,应用运行用户仅拥有必要的数据库权限。

方案选择建议

  • 若追求零凭据存储:优先选方案3(操作系统认证)
  • 若需要跨机器远程连接:优先选方案1(系统凭据存储)或方案2(加密配置文件)
  • 开发环境(Windows)可先用方案1或方案3,保持与生产环境一致的配置逻辑

内容的提问来源于stack exchange,提问作者user10028792

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 08:10:38