环境变量与安全配置:从 .env 加载配置,隐藏密钥

📂 所属阶段:第六阶段 — 上线部署(生产篇)
🔗 相关章节:环境搭建 · 密码安全加密


1. 为什么需要环境变量?

❌ 硬编码密钥:
SECRET_KEY = "abc123..."
API_KEY = "sk-xxxx..."

→ 上传 GitHub → 密钥泄露 → 被恶意使用

✅ 环境变量:
SECRET_KEY = os.getenv("SECRET_KEY")
→ 本地 .env 文件管理 → .gitignore 排除 → 安全!

2. 安装 python-dotenv

pip install python-dotenv

3. 创建配置文件

3.1 .env 文件(本地开发)

# .env(不上传 Git!)
FLASK_ENV=development
SECRET_KEY=dev-only-secret-key-change-in-production
DATABASE_URL=sqlite:///daoman_dev.db
JWT_SECRET=dev-jwt-secret
MAIL_SERVER=smtp.example.com
MAIL_USERNAME=your@email.com
MAIL_PASSWORD=yourpassword

3.2 .env.example(模板)

# .env.example(上传 Git,给协作者参考)
FLASK_ENV=development
SECRET_KEY=change-this-to-a-random-secret
DATABASE_URL=sqlite:///daoman_dev.db
JWT_SECRET=change-this-jwt-secret
MAIL_SERVER=smtp.example.com
MAIL_USERNAME=your@email.com
MAIL_PASSWORD=your-email-password

3.3 .gitignore

# .gitignore
.env
.env.local
.env.production
*.db
__pycache__/
*.pyc
venv/
.venv/
.coverage
htmlcov/
static/uploads/

4. 配置加载

# config.py
import os
from dotenv import load_dotenv

# 加载 .env 文件
load_dotenv()

class Config:
    """基础配置"""
    SECRET_KEY = os.getenv("SECRET_KEY", "fallback-secret")
    SQLALCHEMY_DATABASE_URI = os.getenv("DATABASE_URL", "sqlite:///app.db")
    SQLALCHEMY_TRACK_MODIFICATIONS = False

    # Session 配置
    SESSION_COOKIE_SECURE = True
    SESSION_COOKIE_HTTPONLY = True
    SESSION_COOKIE_SAMESITE = "Lax"

    # Mail 配置
    MAIL_SERVER = os.getenv("MAIL_SERVER")
    MAIL_PORT = int(os.getenv("MAIL_PORT", 587))
    MAIL_USERNAME = os.getenv("MAIL_USERNAME")
    MAIL_PASSWORD = os.getenv("MAIL_PASSWORD")


class DevelopmentConfig(Config):
    DEBUG = True
    SQLALCHEMY_DATABASE_URI = "sqlite:///daoman_dev.db"


class ProductionConfig(Config):
    DEBUG = False
    # 生产环境必须设置真实的 SECRET_KEY
    @classmethod
    def init_app(cls, app):
        Config.init_app(app)
        if app.config["SECRET_KEY"] == "fallback-secret":
            raise ValueError("生产环境必须设置 SECRET_KEY!")


class TestingConfig(Config):
    TESTING = True
    SQLALCHEMY_DATABASE_URI = "sqlite:///:memory:"
    WTF_CSRF_ENABLED = False  # 测试时禁用 CSRF

5. 生产环境部署变量

# 服务器设置环境变量(Shell / Docker / CI-CD)
export SECRET_KEY="your-production-secret"
export DATABASE_URL="postgresql://user:pass@db-server:5432/myapp"
export FLASK_ENV=production

# Docker 方式
docker run -e SECRET_KEY="xxx" -e DATABASE_URL="postgresql://..." myapp

6. 小结

环境变量使用流程:

1. 安装:pip install python-dotenv
2. 创建:.env 文件(不上传 Git)
3. 创建:.env.example(上传 Git)
4. 配置:load_dotenv()
5. 访问:os.getenv("KEY", "默认值")
6. 上线:服务器设置真实环境变量

💡 安全原则:永远不要把密钥、密码、API Key 写进代码仓库。生产环境的密钥使用云平台(AWS Secrets Manager / 阿里云 KMS)或专门的配置中心管理。


🔗 扩展阅读