使用Docker Compose创建一个安全的多数据库中间件服务

使用Docker Compose创建一个安全的多数据库中间件服务

缘由

用AI写了两个程序给同事本地使用,但是不想给所有人提供数据库信息,就问AI有没有好的方法,他提供了一个中间件服务的主意

本文将介绍如何使用Docker Compose创建一个中间件服务,提供对多个MySQL数据库的安全访问。我们将使用Flask构建中间件服务,并通过API密钥进行访问控制。

步骤1:准备配置文件

首先,我们需要一个配置文件来存储多个数据库的连接信息和相应的API密钥。创建一个名为config.json的文件,内容如下:

{
    "databases": {
        "db1": {
            "host": "your_mysql_host1",
            "user": "your_mysql_user1",
            "password": "your_mysql_password1",
            "database": "your_mysql_database1",
            "api_keys": ["api_key_1", "api_key_2"]
        },
        "db2": {
            "host": "your_mysql_host2",
            "user": "your_mysql_user2",
            "password": "your_mysql_password2",
            "database": "your_mysql_database2",
            "api_keys": ["api_key_3", "api_key_4"]
        }
    }
}

在这个配置文件中,每个数据库都有一个唯一的标识符(例如db1db2),并且每个数据库可以有多个API密钥用于访问控制。

步骤2:创建中间件服务代码

接下来,创建一个名为db_service.py的文件,用于实现中间件服务:

from flask import Flask, request, jsonify
import json
import os

app = Flask(__name__)

# 读取配置文件
with open('config.json', 'r') as f:
    config = json.load(f)

def verify_api_key(api_key):
    for db_config in config['databases'].values():
        if api_key in db_config['api_keys']:
            return True
    return False

def get_db_config_by_api_key(api_key):
    for db_name, db_config in config['databases'].items():
        if api_key in db_config['api_keys']:
            return db_name, db_config
    return None, None

@app.route('/get_connection_info', methods=['GET'])
def get_connection_info():
    api_key = request.headers.get('X-API-Key')
    if not verify_api_key(api_key):
        return jsonify({'error': 'Unauthorized'}), 401

    db_name, db_config = get_db_config_by_api_key(api_key)
    if not db_config:
        return jsonify({'error': 'Database not found'}), 404

    connection_info = {
        'host': db_config['host'],
        'user': db_config['user'],
        'database': db_config['database']
    }
    return jsonify(connection_info)

@app.route('/get_password', methods=['GET'])
def get_password():
    api_key = request.headers.get('X-API-Key')
    if not verify_api_key(api_key):
        return jsonify({'error': 'Unauthorized'}), 401

    db_name, db_config = get_db_config_by_api_key(api_key)
    if not db_config:
        return jsonify({'error': 'Database not found'}), 404

    return jsonify({'password': db_config['password']})

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

在这个代码中,我们创建了一个Flask应用,定义了两个API端点:/get_connection_info/get_password。每个端点都使用API密钥进行访问控制。

步骤3:创建Dockerfile

创建一个名为Dockerfile的文件,内容如下:

# 使用官方Python镜像作为基础镜像
FROM python:3.9-slim

# 设置工作目录
WORKDIR /app

# 复制当前目录内容到工作目录
COPY . .

# 安装依赖
RUN pip install flask mysql-connector-python

# 暴露端口
EXPOSE 5000

# 运行应用
CMD ["python", "db_service.py"]

这个Dockerfile定义了一个基本的Python镜像,并安装了Flask和mysql-connector-python包。

步骤4:创建docker-compose.yml

创建一个名为docker-compose.yml的文件,内容如下:

services:
  db_service:
    build: .
    ports:
      - "5000:5000"
    volumes:
      - ./config.json:/app/config.json

这个Compose文件定义了一个服务db_service,构建Docker镜像并将配置文件挂载到容器中。

步骤5:启动中间件服务

在终端中运行以下命令来启动Docker Compose服务:

docker-compose up --build

这将构建并启动中间件服务。

用户代码示例

在用户程序中,通过API密钥从中间件服务获取数据库连接信息并连接到MySQL数据库:

import requests
import mysql.connector
import logging

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# API密钥和中间服务URL
API_KEY = 'API_KEY'
MIDDLEWARE_URL = 'http://localhost:5000'


# 从中间服务获取连接信息
headers = {'X-API-Key': API_KEY}
logging.info("正在获取连接信息...")
connection_info_response = requests.get(f'{MIDDLEWARE_URL}/get_connection_info', headers=headers)
if connection_info_response.status_code != 200:
    logging.error("获取连接信息失败。")
    exit()

connection_info = connection_info_response.json()

logging.info("正在获取密码...")
password_response = requests.get(f'{MIDDLEWARE_URL}/get_password', headers=headers)
if password_response.status_code != 200:
    logging.error("获取密码失败。")
    exit()

password = password_response.json()['password']

# 连接MySQL数据库
logging.info("正在连接到MySQL数据库...")
conn = mysql.connector.connect(
    host=connection_info['host'],
    user=connection_info['user'],
    password=password,
    database=connection_info['database']
)


# 示例查询
cursor = conn.cursor(dictionary=True)
cursor.execute("SELECT now();")
rows = cursor.fetchall()
for row in rows:
    print(row)

conn.close()

通过这种方式,你可以为不同的数据库配置多个API密钥,并通过中间件服务安全地管理对这些数据库的访问。

上一篇 2024年2月11日 下午10:51
下一篇 2024年6月23日 下午10:58

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注