224 lines
6.3 KiB
Markdown
224 lines
6.3 KiB
Markdown
# SSL证书问题解决方案
|
||
|
||
## 【背景意义】
|
||
|
||
在开发环境中连接WordPress API时,经常遇到SSL证书相关错误,特别是`DEPTH_ZERO_SELF_SIGNED_CERT`错误。这类问题会阻止API正常调用,影响开发进度。
|
||
|
||
## 【概念定义】
|
||
|
||
### SSL证书错误类型对比表
|
||
|
||
| 错误类型 | 错误代码 | 含义 | 常见场景 |
|
||
|---------|---------|------|---------|
|
||
| DEPTH_ZERO_SELF_SIGNED_CERT | self-signed certificate | 自签名证书 | 本地开发环境 |
|
||
| CERT_HAS_EXPIRED | certificate has expired | 证书已过期 | 测试环境 |
|
||
| UNABLE_TO_VERIFY_LEAF_SIGNATURE | unable to verify the first certificate | 无法验证证书链 | 配置错误的服务器 |
|
||
| CERT_UNTRUSTED | certificate not trusted | 证书不受信任 | 使用了未知CA的证书 |
|
||
|
||
## 【使用流程】
|
||
|
||
### 方案一:忽略SSL验证(仅开发环境)
|
||
|
||
#### 1. 修改axios配置
|
||
|
||
在`src/service/wp.service.ts`中的`fetchPagedData`方法添加SSL配置:
|
||
|
||
```typescript
|
||
// 在fetchPagedData方法中修改config配置
|
||
const config: AxiosRequestConfig = {
|
||
method: 'GET',
|
||
url: `${wpApiUrl}/wp-json${endpoint}`,
|
||
headers: {
|
||
Authorization: `Basic ${auth}`, // 基础认证头
|
||
},
|
||
params: {
|
||
page, // 当前页码
|
||
per_page: perPage, // 每页数量
|
||
},
|
||
// 添加SSL配置 - 仅用于开发环境
|
||
httpsAgent: new (require('https').Agent)({
|
||
rejectUnauthorized: false // 忽略SSL证书验证
|
||
}),
|
||
// 设置超时时间
|
||
timeout: 30000 // 30秒超时
|
||
};
|
||
```
|
||
|
||
#### 2. 全局axios配置
|
||
|
||
在项目入口文件中添加全局配置:
|
||
|
||
```typescript
|
||
// 在src/configuration.ts或app.ts中添加
|
||
import axios from 'axios';
|
||
import https from 'https';
|
||
|
||
// 仅在开发环境中忽略SSL验证
|
||
if (process.env.NODE_ENV === 'development') {
|
||
axios.defaults.httpsAgent = new https.Agent({
|
||
rejectUnauthorized: false // 忽略自签名证书
|
||
});
|
||
}
|
||
```
|
||
|
||
### 方案二:环境变量控制(推荐)
|
||
|
||
#### 1. 创建环境配置
|
||
|
||
在`.env`文件中添加:
|
||
|
||
```bash
|
||
# SSL配置
|
||
NODE_TLS_REJECT_UNAUTHORIZED=0 # 仅开发环境使用
|
||
WP_API_TIMEOUT=30000 # API超时时间
|
||
WP_API_VERIFY_SSL=false # 是否验证SSL
|
||
```
|
||
|
||
#### 2. 动态SSL配置
|
||
|
||
```typescript
|
||
// 在wp.service.ts中添加动态配置
|
||
import { Config } from '@midwayjs/core';
|
||
|
||
@Provide()
|
||
export class WPService {
|
||
@Config('wpSite')
|
||
sites: Site[];
|
||
|
||
// 获取SSL配置
|
||
private getHttpsAgent() {
|
||
const verifySSL = process.env.WP_API_VERIFY_SSL !== 'false';
|
||
|
||
if (!verifySSL) {
|
||
return new (require('https').Agent)({
|
||
rejectUnauthorized: false // 开发环境忽略SSL验证
|
||
});
|
||
}
|
||
|
||
return undefined; // 生产环境使用默认配置
|
||
}
|
||
|
||
async fetchPagedData<T>(
|
||
endpoint: string,
|
||
site: Site,
|
||
page: number = 1,
|
||
perPage: number = 100
|
||
): Promise<T[]> {
|
||
const { wpApiUrl, consumerKey, consumerSecret } = site;
|
||
const allData: T[] = [];
|
||
|
||
// Base64编码认证信息
|
||
const auth = Buffer.from(`${consumerKey}:${consumerSecret}`).toString('base64');
|
||
|
||
let hasMore = true;
|
||
while (hasMore) {
|
||
const config: AxiosRequestConfig = {
|
||
method: 'GET',
|
||
url: `${wpApiUrl}/wp-json${endpoint}`,
|
||
headers: {
|
||
Authorization: `Basic ${auth}`, // 基础认证
|
||
'Content-Type': 'application/json', // 内容类型
|
||
},
|
||
params: {
|
||
page, // 分页参数
|
||
per_page: perPage, // 每页条数
|
||
},
|
||
httpsAgent: this.getHttpsAgent(), // 动态SSL配置
|
||
timeout: parseInt(process.env.WP_API_TIMEOUT || '30000'), // 超时配置
|
||
};
|
||
|
||
try {
|
||
const response = await axios.request(config);
|
||
|
||
// 添加当前页数据
|
||
allData.push(...response.data);
|
||
|
||
// 检查是否还有更多页
|
||
const totalPages = parseInt(response.headers['x-wp-totalpages'] || '1', 10);
|
||
hasMore = page < totalPages;
|
||
page += 1;
|
||
|
||
} catch (error) {
|
||
// 增强错误处理
|
||
if (error.code === 'DEPTH_ZERO_SELF_SIGNED_CERT') {
|
||
console.error('SSL证书错误:请检查证书配置或在开发环境中忽略SSL验证');
|
||
}
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
return allData;
|
||
}
|
||
}
|
||
```
|
||
|
||
### 方案三:安装自签名证书(生产环境推荐)
|
||
|
||
#### 1. 生成证书
|
||
|
||
```bash
|
||
# 生成私钥
|
||
openssl genrsa -out server.key 2048
|
||
|
||
# 生成证书签名请求
|
||
openssl req -new -key server.key -out server.csr
|
||
|
||
# 生成自签名证书
|
||
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
|
||
```
|
||
|
||
#### 2. 配置服务器
|
||
|
||
将生成的证书配置到WordPress服务器的SSL设置中。
|
||
|
||
## 安全最佳实践
|
||
|
||
### 环境配置对比表
|
||
|
||
| 环境类型 | SSL验证 | 推荐方案 | 安全级别 |
|
||
|---------|---------|---------|---------|
|
||
| 开发环境 | 可忽略 | 环境变量控制 | 低 |
|
||
| 测试环境 | 建议验证 | 使用测试证书 | 中 |
|
||
| 生产环境 | 必须验证 | 有效SSL证书 | 高 |
|
||
|
||
### 代码示例:环境检测
|
||
|
||
```typescript
|
||
// 环境安全检测
|
||
class SSLSecurityChecker {
|
||
static checkEnvironment(): void {
|
||
// 检查是否在生产环境中禁用了SSL验证
|
||
if (process.env.NODE_ENV === 'production' &&
|
||
process.env.NODE_TLS_REJECT_UNAUTHORIZED === '0') {
|
||
throw new Error('生产环境不允许禁用SSL验证!');
|
||
}
|
||
|
||
// 开发环境警告
|
||
if (process.env.NODE_ENV === 'development' &&
|
||
process.env.WP_API_VERIFY_SSL === 'false') {
|
||
console.warn('⚠️ 开发环境已禁用SSL验证,请勿在生产环境使用此配置');
|
||
}
|
||
}
|
||
}
|
||
|
||
// 在应用启动时调用
|
||
SSLSecurityChecker.checkEnvironment();
|
||
```
|
||
|
||
## 故障排查步骤
|
||
|
||
### 排查流程表
|
||
|
||
| 步骤 | 检查项目 | 命令/方法 | 预期结果 |
|
||
|------|---------|----------|---------|
|
||
| 1 | 网络连通性 | `ping wp-test.local` | 能够ping通 |
|
||
| 2 | SSL证书状态 | `openssl s_client -connect wp-test.local:443` | 显示证书信息 |
|
||
| 3 | API端点可访问性 | `curl -k https://wp-test.local/wp-json/wc/v3/` | 返回API信息 |
|
||
| 4 | 认证信息正确性 | 检查Consumer Key/Secret | 密钥格式正确 |
|
||
|
||
## 参考文档
|
||
|
||
- [Node.js HTTPS文档](https://nodejs.org/api/https.html)
|
||
- [Axios配置文档](https://axios-http.com/docs/config_defaults)
|
||
- [WooCommerce REST API文档](https://woocommerce.github.io/woocommerce-rest-api-docs/)
|
||
- [OpenSSL证书生成指南](https://www.openssl.org/docs/) |