不能在gin中间件中对responsewriter做字符串替换,因其非可读缓冲区、破坏json结构、误杀内容且无法处理流式响应;应改用结构体标签+自定义marshaljson实现字段级脱敏,或使用responsewriter包装器拦截write/writeheader。

传输层加密必须用 HTTPS,别在 Gin 中间件里对响应体做字符串替换——这是最常踩的坑,且无法修复 JSON 结构或兼容流式响应。
为什么不能在中间件里 Replace 响应字符串
直接读 ResponseWriter 底层字节、用正则把手机号/邮箱替换成 ****,看似简单,实则破坏性极强:
- ResponseWriter 不是缓冲区,Gin 默认不缓存响应体,你拿到的只是写入接口,不是可读字节流
- JSON 结构会被破坏(比如
"phone":"138****1234"可能误杀字段名中的phone或值里的正常星号) - 触发
http: multiple response.WriteHeader calls错误(因 WriteHeader 被多次调用) - 完全不支持
text/event-stream这类流式响应
传输加密只靠 HTTPS + 正确证书配置
传输过程的安全边界非常清晰:只依赖 TLS 层,和 Gin 逻辑无关。重点是启用和配对:
- 在
server/config.docker.yaml中开启use-https: true,并指定cert-file和key-file - 生产环境必须用可信 CA 签发证书;内网可自签名,但需客户端信任根证书
- 启动时调用
http.ListenAndServeTLS(":443", "cert.pem", "key.pem", router),而非r.Run() - 禁用 HTTP 明文端口,或加 301 重定向(避免混合内容风险)
敏感字段脱敏必须在业务结构体层实现
真正可控、可测试、兼容多格式(JSON/XML/YAML)的方式,是用结构体标签 + 自定义 MarshalJSON:
- 给字段加
redact:"mask"或redact:"email"这类自定义 tag - 在
MarshalJSON方法中判断 tag 并调用MaskPhone()/MaskEmail()等函数 - 用
type Alias User防止递归调用,再构造匿名结构体控制输出字段 - 这种方式天然绕过中间件顺序问题,也兼容 Gin 的
c.JSON()、c.XML()等所有响应方法
JWT 和服务间通信加密是另一层事
HTTPS 解决的是「链路加密」,而 JWT、mTLS、AES-GCM 是解决「身份可信」和「数据内容加密」:
- 用户登录后下发的 JWT,应使用
RS256签名,exp设为短时效(如 15 分钟),且不存敏感信息 -
微服务之间调用,必须走 HTTPS,高安全场景启用
mTLS(ClientAuth: tls.RequireAndVerifyClientCert) - 数据库存储密码必须用
bcrypt,敏感字段(如身份证号)落库前用AES-256-GCM加密,密钥交由 KMS 管理
最容易被忽略的是:脱敏和加密不是同一回事。HTTPS 保传输,结构体 MarshalJSON 控制输出,bcrypt 和 AES 处理存储——三层职责必须分清,混在一起反而增加攻击面。











