# 06 — 安全与日志规则

> **适用**：所有后端开发任务。

---

## 安全规则

### 认证检查（不变式）

每个需要登录的接口必须通过 Shiro 认证。JeecgBoot 默认全局拦截。

```java
// JeecgBoot 认证机制：
// 1. 所有 /sys/** /admin/** 默认需要登录
// 2. 白名单在 application.yml 配置
// 3. 权限注解：@RequiresPermissions / @RequiresRoles

// ✅ 接口加权限
@RequiresPermissions("user:add")
@PostMapping("/add")
public Result<?> add(...) { ... }

// ❌ 不要为了调试临时关认证
// ❌ 不要把需要认证的路径加到 shiro.excludeUrls
```

### 数据权限（租户隔离）

JeecgBoot 已通过 MyBatis-Plus 拦截器自动注入 tenant_id，**但如果手写 SQL 必须手动加**。

```java
// ✅ 用 MyBatis-Plus 自动处理
taskService.list(new LambdaQueryWrapper<Task>().eq(Task::getStatus, "pending"));

// ❌ 手写 SQL 忘了加租户 → 租户A 看到租户B 的数据
@Select("SELECT * FROM task WHERE status = #{status}")

// ✅ 手写 SQL 正确写法
@Select("SELECT * FROM task WHERE status = #{status} AND tenant_id = #{tenantId}")
```

### 敏感信息保护

```java
// ✅ 密码字段不返回
@Entity
public class SysUser {
    @JsonIgnore  // ← 关键
    private String password;
}

// ✅ 手机号脱敏返回（VO 层处理）
userVO.setPhone(phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"));
```

### 文件上传安全

```java
// ✅ 必须校验（JeecgBoot 已内置部分，确认开启）
- 文件类型白名单：只允许 jpg/png/pdf/doc/xlsx
- 文件大小上限：单文件 ≤ 10MB
- 文件名处理：用 UUID 重命名，防路径穿越
- 存储路径：不暴露原始文件名给前端
```

### 接口防刷

```java
// ✅ 敏感接口（登录/短信/支付）加限流
// JeecgBoot 使用 Sentinel 或自定义注解
@RateLimiter(count = 5, time = 60)  // 60秒内最多5次
@PostMapping("/send-sms")
public Result<?> sendSms(...) { ... }
```

---

## 日志规则

### 日志级别

| 级别 | 场景 |
|------|------|
| ERROR | 数据库连不上、第三方接口失败、业务异常需要人工介入 |
| WARN | 降级处理、重试成功、配置缺失但有默认值 |
| INFO | 用户登录、任务创建、状态变更、定时任务执行 |
| DEBUG | 开发调试用，不入生产 |

### 日志内容

```java
// ✅ 关键操作
log.info("任务状态变更 taskId={} from={} to={} operator={}", taskId, oldStatus, newStatus, userId);

// ✅ 异常
log.error("调用第三方接口失败 url={}", url, e);  // 最后一个参数是异常对象

// ❌ 不要这样
log.info("进来了");
log.info("user=" + user.toString());  // 可能打印密码
System.out.println("debug: " + xxx);  // 永远不
```

### 禁止

| ❌ | 原因 |
|----|------|
| 循环里打 INFO | 日志爆炸 |
| 打印完整大对象 | 刷屏且可能泄露敏感数据 |
| 用 System.out.println | 不入日志文件 |
| 用 e.printStackTrace() | 不入日志框架 |


---

## 检查表

- [ ] 新接口需要认证（不在白名单中）
- [ ] 手写 SQL 加了租户隔离
- [ ] 敏感字段不返回给前端
- [ ] 文件上传有类型/大小校验
- [ ] 关键操作有 INFO 日志
- [ ] 异常有 ERROR 日志（带栈）
- [ ] 无硬编码密码/密钥
