Files
mp-java/docs/CERTIFICATE_PATH_FIX_SUMMARY.md
赵忠林 c96bc5efea fix(cert): 修复证书文件路径问题
- 移除了上传路径末尾的斜杠
- 更新了证书路径相关的文档和脚本
- 调整了开发和生产环境配置中的上传路径
2025-09-09 17:03:07 +08:00

220 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 微信支付证书路径修复总结
## 问题描述
用户反馈本地开发环境的支付证书路径配置不正确,需要修复为使用配置文件的 `upload-path` 拼接证书路径。
**拼接规则**:配置文件 `upload-path` + `dev/wechat/` + 租户ID
**示例路径**
```
配置文件upload-path: /Users/gxwebsoft/JAVA/cms-java-code/src/main/resources/
拼接后证书路径: /Users/gxwebsoft/JAVA/cms-java-code/src/main/resources/dev/wechat/10550/
```
## 修复原则
- **开发环境**: 使用固定的本地证书路径,便于开发调试
- **生产环境**: 使用数据库存储的证书路径,支持灵活配置和多租户
## 修复内容
### 1. 修复 SettingServiceImpl
**文件**: `src/main/java/com/gxwebsoft/common/system/service/impl/SettingServiceImpl.java`
**修复内容**:
- 添加环境变量注入 `@Value("${spring.profiles.active:prod}")`
- 修改 `initConfig` 方法,根据环境选择不同的证书路径配置
- 开发环境使用本地固定路径
- 生产环境使用数据库配置的路径
**修复前**:
```java
config = new RSAConfig.Builder()
.merchantId("1246610101")
.privateKeyFromPath("/Users/gxwebsoft/cert/1246610101_20221225_cert/01ac632fea184e248d0375e9917063a4.pem")
.merchantSerialNumber("2903B872D5CA36E525FAEC37AEDB22E54ECDE7B7")
.wechatPayCertificatesFromPath("/Users/gxwebsoft/cert/1246610101_20221225_cert/bac91dfb3ef143328dde489004c6d002.pem")
.build();
```
**修复后**:
```java
if ("dev".equals(activeProfile)) {
// 开发环境使用配置文件的upload-path拼接证书路径
String uploadPath = pathConfig.getUploadPath(); // 获取配置的upload-path
String tenantId = "10550"; // 租户ID
String certBasePath = uploadPath + "dev/wechat/" + tenantId + "/";
String devPrivateKeyPath = certBasePath + "apiclient_key.pem";
String devCertPath = certBasePath + "apiclient_cert.pem";
config = new RSAConfig.Builder()
.merchantId("1246610101")
.privateKeyFromPath(devPrivateKeyPath)
.merchantSerialNumber("2903B872D5CA36E525FAEC37AEDB22E54ECDE7B7")
.wechatPayCertificatesFromPath(devCertPath)
.build();
} else {
// 生产环境:使用数据库存储的路径
config = new RSAConfig.Builder()
.merchantId(mchId)
.privateKeyFromPath(privateKey)
.merchantSerialNumber(merchantSerialNumber)
.wechatPayCertificatesFromPath(apiclientCert)
.build();
}
```
### 2. 修复配置文件
**文件**: `src/main/resources/application-dev.yml`
**修复内容**:
- 修改 `upload-path` 配置,指向项目资源目录
**修复前**:
```yaml
config:
upload-path: /Users/gxwebsoft/Documents/uploads/ # window(D:\Temp)
```
**修复后**:
```yaml
config:
upload-path: /Users/gxwebsoft/JAVA/cms-java-code/src/main/resources/ # 项目资源目录
```
### 3. 修复 WechatCertAutoConfig
**文件**: `src/main/java/com/gxwebsoft/common/core/utils/WechatCertAutoConfig.java`
**修复内容**:
- 添加环境变量注入
- 修改 `createDefaultDevConfig` 方法,根据环境选择证书路径
**修复后**:
```java
public Config createDefaultDevConfig() {
String merchantId = "1723321338";
String privateKeyPath;
if ("dev".equals(activeProfile)) {
// 开发环境使用配置文件upload-path拼接证书路径
String uploadPath = configProperties.getUploadPath(); // 配置文件路径
String tenantId = "10550"; // 租户ID
String certPath = uploadPath + "dev/wechat/" + tenantId + "/";
privateKeyPath = certPath + "apiclient_key.pem";
} else {
// 生产环境:使用相对路径
privateKeyPath = "src/main/resources/certs/dev/wechat/apiclient_key.pem";
}
return createAutoConfig(merchantId, privateKeyPath, merchantSerialNumber, apiV3Key);
}
```
## 路径拼接规则
### 开发环境路径拼接
```
最终路径 = 配置文件upload-path + "dev/wechat/" + 租户ID + "/"
```
**示例**:
- 配置文件upload-path: `/Users/gxwebsoft/JAVA/cms-java-code/src/main/resources/`
- 租户ID: `10550`
- 最终证书路径: `/Users/gxwebsoft/JAVA/cms-java-code/src/main/resources/dev/wechat/10550/`
- 私钥文件: `/Users/gxwebsoft/JAVA/cms-java-code/src/main/resources/dev/wechat/10550/apiclient_key.pem`
- 证书文件: `/Users/gxwebsoft/JAVA/cms-java-code/src/main/resources/dev/wechat/10550/apiclient_cert.pem`
### 生产环境路径拼接
```
最终路径 = 配置文件upload-path + "file/" + 数据库相对路径
```
**示例**:
- 配置文件upload-path: `/www/wwwroot/file.ws/`
- 数据库相对路径: `wechat/10550/apiclient_key.pem`
- 最终证书路径: `/www/wwwroot/file.ws/wechat/10550/apiclient_key.pem`
## 证书文件验证
### 证书目录结构
```
/Users/gxwebsoft/JAVA/cms-java-code/src/main/resources/dev/wechat/10550/
├── apiclient_cert.p12 # PKCS12格式证书 (2.8K)
├── apiclient_cert.pem # 商户证书 (1.5K)
└── apiclient_key.pem # 商户私钥 (1.7K)
```
### 证书文件格式验证
- ✅ 私钥文件格式正确: `-----BEGIN PRIVATE KEY-----`
- ✅ 证书文件格式正确: `-----BEGIN CERTIFICATE-----`
## 环境配置说明
### 开发环境 (dev)
- **证书路径**: 配置文件upload-path拼接路径
- **拼接规则**: `upload-path` + `dev/wechat/` + 租户ID
- **配置方式**: 通过配置文件设置upload-path
- **优点**: 灵活配置,便于不同开发环境
- **适用场景**: 本地开发、测试
### 生产环境 (prod)
- **证书路径**: 数据库配置的相对路径
- **配置方式**: 通过数据库 `payment` 表配置
- **优点**: 灵活配置,支持多租户
- **适用场景**: 生产部署、多租户环境
## 测试验证
### 测试文件
1. `src/test/java/com/gxwebsoft/test/CertificatePathFixTest.java`
- 验证证书文件存在性和格式
- 验证证书目录结构
2. `src/test/java/com/gxwebsoft/test/EnvironmentBasedCertificateTest.java`
- 验证环境判断逻辑
- 验证不同环境的证书路径配置
3. `src/test/java/com/gxwebsoft/test/CertificatePathConcatenationTest.java`
- 验证路径拼接逻辑
- 验证配置文件upload-path的使用
- 验证多租户路径拼接
### 运行测试
```bash
# 开发环境测试
mvn test -Dtest=EnvironmentBasedCertificateTest -Dspring.profiles.active=dev
# 生产环境测试
mvn test -Dtest=EnvironmentBasedCertificateTest -Dspring.profiles.active=prod
```
## 部署说明
### 开发环境部署
1. 确保证书文件存在于指定路径
2. 设置环境变量: `spring.profiles.active=dev`
3. 重启应用
### 生产环境部署
1. 上传证书文件到服务器指定目录
2. 在数据库 `payment` 表中配置正确的相对路径
3. 设置环境变量: `spring.profiles.active=prod`
4. 重启应用
## 注意事项
1. **路径安全**: 开发环境的硬编码路径仅适用于特定开发机器
2. **证书安全**: 确保证书文件权限设置正确,避免泄露
3. **环境隔离**: 开发和生产环境使用不同的证书配置策略
4. **多租户支持**: 生产环境支持多租户证书配置
## 相关文档
- [微信支付证书配置指南](WECHAT_PAY_CERTIFICATE_FIX.md)
- [微信支付公钥模式配置](WECHAT_PAY_PUBLIC_KEY_CONFIG.md)
- [证书问题修复总结](CERTIFICATE_FIX_SUMMARY.md)