You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Django使用mysql数据库后端时,如何实现MySQL服务器SSL认证的VERIFY_IDENTITY模式?

Django使用mysql数据库后端时,如何实现MySQL服务器SSL认证的VERIFY_IDENTITY模式?

嘿,我之前也碰到过这个问题!确实Django官方的MySQL后端文档里没明确提到如何开启VERIFY_IDENTITY模式,不过咱们可以通过驱动参数或者自定义后端两种方式解决,我给你详细拆解下:

首先得明确:你当前的配置已经启用了SSL加密通道(通过ca参数开启了VERIFY_CA模式),但VERIFY_IDENTITY还多了一步——验证服务器证书中的主机名(CN/SAN字段)是否和你配置的DB_HOST完全匹配,这能防止中间人攻击,安全性更高。

方法一:直接通过驱动参数配置(推荐)

Django的MySQL后端会把OPTIONS里的参数传递给底层的数据库驱动(比如mysqlclientpymysql),咱们可以直接添加对应参数开启VERIFY_IDENTITY

如果你用的是Django推荐的mysqlclient驱动:

直接在OPTIONS里新增ssl_mode参数,同时保留原有的ssl字典配置:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': env('DB_NAME'),
        'USER': env('DB_USER'),
        'PASSWORD': env('DB_PASSWORD'),
        'HOST': env('DB_HOST'),
        'PORT': env('DB_PORT'),
        'CONN_MAX_AGE': 600,
        'OPTIONS':{
            'ssl':{
                'ca': env('CA_CERT'),
                'cert': env('CERT'),
                'key': env('KEY')
            },
            'ssl_mode': 'VERIFY_IDENTITY'  # 新增这一行
        }
    }
}

如果你用的是pymysql驱动:

需要把mode参数放到ssl字典里:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': env('DB_NAME'),
        'USER': env('DB_USER'),
        'PASSWORD': env('DB_PASSWORD'),
        'HOST': env('DB_HOST'),
        'PORT': env('DB_PORT'),
        'CONN_MAX_AGE': 600,
        'OPTIONS':{
            'ssl':{
                'ca': env('CA_CERT'),
                'cert': env('CERT'),
                'key': env('KEY'),
                'mode': 'VERIFY_IDENTITY'  # 把mode放到ssl字典里
            }
        }
    }
}

方法二:自定义数据库后端(兼容旧版本)

如果上面的方法因为驱动/Django版本太旧不生效,可以自定义一个MySQL后端,手动注入ssl_mode参数:

  1. 在你的Django项目里创建一个backends目录,新建mysql.py文件,内容如下:
from django.db.backends.mysql.base import DatabaseWrapper

class CustomMySQLBackend(DatabaseWrapper):
    def get_new_connection(self, conn_params):
        # 强制添加VERIFY_IDENTITY模式
        conn_params['ssl_mode'] = 'VERIFY_IDENTITY'
        return super().get_new_connection(conn_params)
  1. 修改DATABASESENGINE指向这个自定义后端:
DATABASES = {
    'default': {
        'ENGINE': 'your_app_name.backends.mysql.CustomMySQLBackend',  # 替换成你的app名
        # 其他配置和你原来的一样...
        'OPTIONS':{
            'ssl':{
                'ca': env('CA_CERT'),
                'cert': env('CERT'),
                'key': env('KEY')
            }
        }
    }
}

关键注意点

  • 确保你的MySQL服务器证书里的CN字段或者SAN扩展包含你配置的DB_HOST值(如果是IP,证书里要加IP的SAN;如果是域名,要加域名的SAN/CN),否则验证会失败!
  • 测试验证:你可以故意把DB_HOST改成一个和证书不匹配的值,比如用服务器的IP但证书里只有域名,此时连接应该报错,说明VERIFY_IDENTITY已经生效了。

这样应该就能满足你的需求啦,我之前用第一种方法在多个项目里都跑通了,没问题的!

火山引擎 最新活动