3.2 KiB
3.2 KiB
06 — 安全与日志规则
适用:所有后端开发任务。
安全规则
认证检查(不变式)
每个需要登录的接口必须通过 Shiro 认证。JeecgBoot 默认全局拦截。
// 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 必须手动加。
// ✅ 用 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}")
敏感信息保护
// ✅ 密码字段不返回
@Entity
public class SysUser {
@JsonIgnore // ← 关键
private String password;
}
// ✅ 手机号脱敏返回(VO 层处理)
userVO.setPhone(phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"));
文件上传安全
// ✅ 必须校验(JeecgBoot 已内置部分,确认开启)
- 文件类型白名单:只允许 jpg/png/pdf/doc/xlsx
- 文件大小上限:单文件 ≤ 10MB
- 文件名处理:用 UUID 重命名,防路径穿越
- 存储路径:不暴露原始文件名给前端
接口防刷
// ✅ 敏感接口(登录/短信/支付)加限流
// JeecgBoot 使用 Sentinel 或自定义注解
@RateLimiter(count = 5, time = 60) // 60秒内最多5次
@PostMapping("/send-sms")
public Result<?> sendSms(...) { ... }
日志规则
日志级别
| 级别 | 场景 |
|---|---|
| ERROR | 数据库连不上、第三方接口失败、业务异常需要人工介入 |
| WARN | 降级处理、重试成功、配置缺失但有默认值 |
| INFO | 用户登录、任务创建、状态变更、定时任务执行 |
| DEBUG | 开发调试用,不入生产 |
日志内容
// ✅ 关键操作
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 日志(带栈)
- 无硬编码密码/密钥