3. 核心原则:数据最小化、目的限制、存储限制

这三条原则放在一起讲,是因为它们在实际工作中几乎绑在一起。我见过太多项目把「收集用户数据」当成默认行为,反正先存着,以后说不定有用。嗯,这种思路在合规面前几乎就是火坑。

说白了,数据保护不是让你别碰数据,而是让你想清楚:真的需要这个字段吗?用来干嘛?用完能删吗? 今天咱们拆开揉碎了聊。

数据保护核心原则:最小化 · 目的限制 · 存储限制 数据最小化 只收集必要字段 目的限制 收集时明确用途 存储限制 设定保留与删除策略 1. 字段逐项评审:“能不加吗?” 2. 用途写进用户同意书 3. 设置 TTL 自动清理 核心逻辑 收集前问“为什么” → 使用中问“给谁用” → 存储后问“何时删” 三条原则相互制衡,缺一不可。

3.1 数据最小化:别一股脑全收

数据最小化的意思很简单:只收集你当下需要的东西。你想想看,用户注册一个论坛账号,你非要收集人家的精确地理位置,这合理吗?不合理。

我曾经接手过一个遗留项目,用户表的字段超过40个。包括「最喜欢的颜色」「配偶生日」「工作单位地址」——而整个业务只需要用户名和邮箱。你猜后来怎么样?数据泄露时监管罚了300万,其中一条就是违反数据最小化原则。

我的建议: 设计接口时,response 字段不要用 SELECT *。指定你需要的字段,多余的别返回。请求体同理,能只传 ID 就别传整个对象。

实操检查清单

  • 每个字段写下来,问自己:去掉它业务还能跑吗?
  • 能用匿名/脱敏数据替代原始数据吗?
  • 用户提供的非必填信息,是否真的有必要存入数据库?

我在项目中习惯在 API 设计文档里加一列「合规理由」,每个字段旁边标注为什么需要它。没有理由的字段,直接删。

注意: 不要抱着“以后可能会用”的心态提前收集额外数据。除非你有明确的法律依据和用户同意,否则就是违规。曾经有家电商公司因为收集用户「浏览时长」用于未来可能的功能,被告到隐私监管机构,最后赔了和解金。

3.2 目的限制:说好干嘛就干嘛

目的限制和数据最小化是双胞胎。你收集数据的时候,得告诉用户:你打算用这些数据做什么?而且只能用在这个用途上。

举个例子:用户注册时同意你把邮箱用于登录验证。回头你用这个邮箱发营销邮件——对不起,那是另一个目的,需要单独授权。

场景 允许用途 禁止用途
用户注册 登录、账户管理 用于第三方广告推荐
订单支付 生成收据、物流通知 用于客户画像分析
客服反馈 回复问题、改进服务 用于营销电话

我还见过一个更隐蔽的坑:业务方说“用户同意了隐私协议”,但协议里把目的写得像小说一样长。说白了,这叫模糊授权,合规上基本站不住脚。我个人习惯是:每个数据用途独立成段,用户勾选时才视为同意,而不是搞一个大包裹条款。

技术落地建议: 在 API 设计时,为每个用途分配一个「用途 ID」(purpose ID)。数据访问层根据用途 ID 做鉴权。比如读取用户邮箱只有「登录验证」这个 purpose ID 才能拿到,其他模块调用直接返回 null。这比后期加权限省事得多。

3.3 存储限制:数据不能长生不老

这条原则特别容易被忽视。很多团队觉得硬盘便宜,存着也不占地方。但你想想,数据存得越久,被泄露的风险越大,合规成本也越高。监管明确要求:数据保存期限不得超过实现其处理目的所需的时间。

我曾经帮一个金融客户做合规审查,发现他们五年的交易数据全保留着,连用户注销后的记录都没删。为什么?因为他们做风控模型需要历史数据。但这个“需要”完全没有定义清理策略。最后我们给每个数据表加了一个 retention_days 字段,并用定时任务每天清理过期数据。

存储期限设置示例

  • 用户会话日志:保留 7 天
  • 订单支付记录:保留至法律诉讼时效到期(通常 3-5 年)
  • 临时缓存数据:TTL 不超过 1 小时
  • 用户上传的文件:用户删除后立即不可访问,30 天后物理删除
避坑小技巧: 设置自动删除任务时,千万别直接 DELETE FROM 就走人。我曾经遇到过一个大表删除导致锁表,线上服务挂了半小时。建议分批删除,或者用逻辑删除 + 后台异步清理。另外记得提前备份审计日志,以防合规审查需要。

3.4 三条原则在 API 设计中的综合应用

好了,三条原则讲完了。实际写接口时怎么一起落地?我拿一个常见的「用户资料查询接口」举例:

// 不推荐的做法
GET /api/v1/user/profile

Response:
{
  "userId": 123,
  "email": "test@example.com",
  "phone": "13800138000",
  "address": "北京市海淀区...",
  "gender": "male",
  "birthday": "1990-01-01",
  "lastLoginIp": "192.168.1.1",
  "createdAt": "2020-01-01T00:00:00Z"
}

这个接口违反了三条原则中的每一条:

  • 数据最小化:前端只需要显示昵称和头像,你返回了一堆敏感字段。
  • 目的限制:用户没有授权你提供生日和 IP 给前端。
  • 存储限制:IP 地址不应该长期保留在用户资料表中。
// 推荐的做法:按用途拆分
GET /api/v1/user/profile/basic   // 用途:显示个人信息
Response: { "nickname": "小明", "avatar": "..." }

GET /api/v1/user/profile/contact // 用途:账户安全验证(需额外授权)
Response: { "email": "test@example.com", "phone": "138****8000" }

我个人习惯在接口文档里,对每个字段标注「最小化理由」和「保留期限」。比如 phone 字段:理由 = “双因子验证”,保留期限 = “用户注销后 30 天”。这种文档看起来累,但审计的时候就是护身符。

再次提醒: 千万不要把用户数据一股脑塞进日志里!我见过一个真实案例:某公司把用户注册的明文密码写进了错误日志,结果日志被运维人员导出,酿成大规模账号泄露。存储数据前,先问问自己:这个数据不存行不行?存了多久删?

好了,今天这章就聊到这儿。三条原则其实就是一个核心思想:别把用户数据当成可以无限持有的资产,它更像借来的东西,用完了要还回去(删掉)。记住这个比喻,你设计接口时就不会跑偏。