企业级对外开放接口安全校验方案设计、数据库设计和代码实现
外部开放接口 IP 白名单、签名校验与防重放设计方案1. 需求理解本文档用于设计一套外部系统访问项目开放接口的安全控制方案。核心目标:外部 IP 必须在白名单中,才允许访问开放接口。不同 IP 可以配置不同的允许访问接口。外部开放接口需要增加签名校验,防止请求被篡改。外部开放接口需要增加时间戳和 nonce 校验,防止请求被重放。每次访问都需要记录访问日志,方便后续审计、排查和统计。整体访问流程如下:外部系统请求 ↓ 获取真实客户端 IP ↓ 校验调用方 clientCode 是否存在且启用 ↓ 校验 IP 是否在该调用方白名单中 ↓ 校验该 IP 是否允许访问当前接口 ↓ 校验 timestamp 是否在允许时间窗口内 ↓ 校验 nonce 是否已使用,防止重放请求 ↓ 校验 HMAC-SHA256 签名 ↓ 校验通过:放行业务接口,并记录访问成功日志 校验失败:拒绝访问,并记录失败日志2. 模块设计建议拆分为 5 张表:hb_open_api_client 外部调用方密钥表 hb_open_api_ip_white IP 白名单地址表 hb_open_api_ip_interface IP 允许访问接口表 hb_open_api_nonce_record nonce 防重放记录表 hb_open_api_access_log 外部 IP 访问记录表表关系如下:hb_open_api_client 1 对 多 hb_open_api_ip_white 1 对 多 hb_open_api_ip_interface hb_open_api_client 1 对 多 hb_open_api_nonce_record hb_open_api_client / hb_open_api_ip_white / hb_open_api_ip_interface 1 对 多 hb_open_api_access_log职责划分:表名作用hb_open_api_client维护外部调用方身份、密钥、签名算法、时间戳窗口hb_open_api_ip_white维护某个调用方允许访问的 IP 地址hb_open_api_ip_interface维护某个白名单 IP 允许访问哪些接口hb_open_api_nonce_record记录已使用 nonce,防止同一个请求重复提交hb_open_api_access_log记录外部开放接口访问日志3. 请求头规范外部系统请求开放接口时,建议统一携带以下请求头:X-Client-Code: 外部调用方编码 X-Timestamp: 当前毫秒时间戳 X-Nonce: 随机字符串,每次请求必须唯一 X-Signature: HMAC-SHA256 签名示例:POST /sale/openApi/order/sync HTTP/1.1 Host: api.example.com Content-Type: application/json X-Client-Code: ERP_SYSTEM X-Timestamp: 1782960000000 X-Nonce: 9d4c06e6c8d74a4e88c2c8c7a9d5e001 X-Signature: 7b13f6c4d3c2b1a0xxxxxxxxxxxxxxxx4. 数据库表结构设计4.1 外部调用方密钥表CREATETABLE`hb_open_api_client`(`id`bigintNOTNULLAUTO_INCREMENTCOMMENT'主键ID',`client_name`varchar(100)NOTNULLCOMMENT'外部调用方名称',`client_code`varchar(64)NOTNULLCOMMENT'外部调用方编码',`app_key`varchar(128)NOTNULLCOMMENT'调用方AppKey',`app_secret`varchar(255)NOTNULLCOMMENT'调用方密钥,建议加密存储',`sign_type`varchar(20)NOTNULLDEFAULT'HMAC_SHA256'COMMENT'签名算法',`timestamp_window`intNOTNULLDEFAULT300COMMENT'时间戳允许误差,单位秒',`status`char(1)NOTNULLDEFAULT'0'COMMENT'状态:0启用,1停用',`expire_time`datetimeDEFAULTNULLCOMMENT'过期时间,为空表示长期有效',`create_by`varchar(64)DEFAULT''COMMENT'创建者',`create_time`datetimeDEFAULTCURRENT_TIMESTAMPCOMMENT'创建时间',`update_by`varchar(64)DEFAULT''COMMENT'更新者',`update_time`datetimeDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMPCOMMENT'更新时间',`remark`varchar(500)DEFAULTNULLCOMMENT'备注',`del_flag`char(1)NOTNULLDEFAULT'0'COMMENT'删除标志:0正常,1删除',PRIMARYKEY(`id`),UNIQUEKEY`uk_client_code_del`(`client_code`,`del_flag`),KEY`idx_status_expire`(`status`,`expire_time`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4COMMENT='外部开放接口调用方密钥表';4.2 IP 白名单地址表CREATETABLE`hb_open_api_ip_white`(`id`bigintNOTNULLAUTO_INCREMENTCOMMENT'主键ID',`client_id`bigintNOTNULLCOMMENT'外部调用方ID',`ip_addr`varchar(45)NOTNULLCOMMENT'白名单IP地址,支持IPv4/IPv6',`status`char(1)NOTNULLDEFAULT'0'COMMENT'状态:0启用,1停用',`expire_time`datetimeDEFAULTNULLCOMMENT'过期时间,为空表示长期有效',`last_access_time`datetimeDEFAULTNULLCOMMENT'最近访问时间',`access_count`bigintNOTNULLDEFAULT0COMMENT'累计访问次数',`create_by`varchar(64)DEFAULT''COMMENT'创建者',`create_time`datetimeDEFAULTCURRENT_TIMESTAMPCOMMENT'创建时间',`update_by`varchar(64)DEFAULT''COMMENT'更新者',`update_time`datetimeDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMPCOMMENT'更新时间',`remark`varchar(500)DEFAULTNULLCOMMENT'备注',`del_flag`char(1)NOTNULLDEFAULT'0'COMMENT'删除标志:0正常,1删除',PRIMARYKEY(`id`),UNIQUEKEY`uk_client_ip_del`(`client_id`,`ip_addr`,`del_flag`),KEY`idx_ip_status`(`ip_addr`,`status`),KEY`idx_client_status`(`client_id`,`status`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4COMMENT='外部开放接口IP白名单地址表';4.3 IP 允许访问接口表CREATETABLE