# 百家号 Cookie 验证改进

## 改进内容

将百家号的 Cookie 验证从浏览器检查改为 API 接口检查，提高验证的准确性和效率。

## API 接口

**接口地址**：`https://baijiahao.baidu.com/builder/app/appinfo`

**请求方法**：GET

**请求头**：
```
Cookie: <账号的 Cookie 字符串>
Referer: https://baijiahao.baidu.com/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...
```

## 返回值格式

### 成功响应（Cookie 有效）

```json
{
  "errno": 0,
  "errmsg": "success",
  "data": {
    "user": {
      "app_id": 1833101008440434,
      "name": "三千痴缠坠花湮",
      "userid": 441651849,
      "status": "audit",
      "avatar": "//pic.rmb.bdstatic.com/...",
      ...
    }
  }
}
```

### 失败响应（Cookie 无效）

```json
{
  "errno": 110,
  "errmsg": "未登录",
  "data": null
}
```

## 验证逻辑

### 1. 判断 Cookie 有效的条件

Cookie 被认为有效，需要同时满足以下条件：

1. **errno 为 0**：表示请求成功
2. **有用户信息**：`data.user.name` 或 `data.user.app_id` 存在
3. **用户状态正常**：`data.user.status` 为 `audit`、`pass`、`active` 或不存在

### 2. 判断 Cookie 无效的情况

以下情况表示 Cookie 无效：

1. **errno 非 0**：
   - `errno: 110` - 未登录
   - 其他非 0 值 - 权限问题或其他错误

2. **errno 为 0 但没有用户信息**：
   - 请求成功但返回的 `data.user` 为空
   - 可能是 Cookie 部分失效

3. **用户状态异常**：
   - `status: 'banned'` - 账号被封禁
   - 其他异常状态

## 代码实现

### 配置（`server/src/services/HeadlessBrowserService.ts`）

```typescript
baijiahao: {
  checkUrl: 'https://baijiahao.baidu.com/builder/app/appinfo',
  isValidResponse: (data: unknown) => {
    const resp = data as { 
      errno?: number; 
      errmsg?: string;
      data?: { 
        user?: { 
          name?: string; 
          app_id?: string | number;
          status?: string;
        } 
      } 
    };
    
    // errno 为 0 表示请求成功
    const isErrnoOk = resp?.errno === 0;
    
    // 必须有用户信息
    const hasUserInfo = !!(resp?.data?.user?.name || resp?.data?.user?.app_id);
    
    // 用户状态正常
    const userStatus = resp?.data?.user?.status;
    const isStatusOk = !userStatus || 
                       userStatus === 'audit' || 
                       userStatus === 'pass' || 
                       userStatus === 'active';
    
    return isErrnoOk && hasUserInfo && isStatusOk;
  },
}
```

### 错误处理

```typescript
if (platform === 'baijiahao') {
  const errno = (data as { errno?: number })?.errno;
  
  if (errno === 0) {
    // 请求成功，但可能没有用户信息
    if (!isValid) {
      logger.warn('Baijiahao errno=0 but no user info');
      return false;
    }
    return true;
  }
  
  // errno 非 0，Cookie 无效
  logger.warn(`Baijiahao errno=${errno}, cookie invalid`);
  return false;
}
```

## 优势

### 1. 更快的验证速度
- API 请求比浏览器检查快得多
- 不需要启动无头浏览器
- 减少资源消耗

### 2. 更准确的判断
- 直接从 API 获取用户信息
- 避免浏览器重定向的不确定性
- 可以获取详细的错误信息

### 3. 更好的错误处理
- 根据 errno 判断具体的错误类型
- 可以区分"未登录"和"权限不足"
- 提供更详细的日志信息

## 测试方法

### 1. 测试有效的 Cookie

```bash
curl 'https://baijiahao.baidu.com/builder/app/appinfo' \
  -H 'Cookie: BDUSS=xxx; STOKEN=xxx; ...' \
  -H 'Referer: https://baijiahao.baidu.com/'
```

**预期结果**：
```json
{
  "errno": 0,
  "data": {
    "user": {
      "name": "账号名称",
      "app_id": 123456
    }
  }
}
```

### 2. 测试无效的 Cookie

```bash
curl 'https://baijiahao.baidu.com/builder/app/appinfo' \
  -H 'Cookie: BDUSS=invalid; STOKEN=invalid;' \
  -H 'Referer: https://baijiahao.baidu.com/'
```

**预期结果**：
```json
{
  "errno": 110,
  "errmsg": "未登录"
}
```

## 常见错误码

| errno | 含义 | 处理方式 |
|-------|------|---------|
| 0 | 成功 | 检查是否有用户信息 |
| 110 | 未登录 | Cookie 无效，需要重新登录 |
| 其他 | 其他错误 | Cookie 可能无效或权限不足 |

## 日志示例

### 成功验证

```
[Baijiahao] API response: errno=0, errmsg=success, user.name=三千痴缠坠花湮, user.app_id=1833101008440434, user.status=audit
API check cookie for baijiahao: valid=true, statusCode=0
```

### 失败验证

```
[Baijiahao] API response: errno=110, errmsg=未登录, user.name=undefined, user.app_id=undefined, user.status=undefined
[Baijiahao] Cookie invalid: errno=110, hasUserInfo=false, status=undefined
[API] Baijiahao errno=110, cookie is invalid
API check cookie for baijiahao: valid=false, statusCode=110
```

## 注意事项

1. **网络错误处理**：如果 API 请求失败（网络错误），不应该判定为 Cookie 无效
2. **超时处理**：API 请求应该设置合理的超时时间
3. **重试机制**：对于网络错误，可以考虑重试
4. **日志记录**：记录详细的请求和响应信息，便于调试

## 后续优化

1. **缓存验证结果**：避免频繁请求 API
2. **批量验证**：支持一次验证多个账号
3. **异步验证**：在后台定期验证所有账号的 Cookie
4. **提前预警**：在 Cookie 即将过期时提醒用户
