http请求/响应日志必须在字节流层面脱敏,因结构化后正则替换会破坏json、遗漏嵌套字段且易panic;dumprequestout/dumpresponse会消耗body导致后续读取为空,需手动重放body并慎用深拷贝。

HTTP 请求和响应日志必须在字节流层面做脱敏,不能等结构体序列化完再正则替换——那会破坏 JSON 格式、漏掉嵌套字段、还可能 panic。
为什么 DumpRequestOut/DumpResponse 之后不能直接打日志
因为 httputil.DumpRequestOut 和 httputil.DumpResponse 会消费 req.Body 和 resp.Body 的 io.ReadCloser,导致后续 handler 或 decoder 拿不到原始数据。
- 常见错误:调用
httputil.DumpRequestOut(req, true)后,json.NewDecoder(req.Body)读到空 body,解码失败 - 必须手动重放 body:
bodyBytes, _ := io.ReadAll(req.Body)→req.Body = io.NopCloser(bytes.NewReader(bodyBytes)) -
DumpResponse第二个参数设为false可跳过响应体 dump,避免大文件阻塞和内存暴涨 - 这两个函数内部做深拷贝,高并发下有明显性能开销,别无节制启用
Authorization、Cookie 等 Header 怎么安全脱敏
Header 是最高危字段之一,但不在 req.URL 或 req.PostForm 里,必须单独处理。
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
- 别只扫 query 和 form,
req.Header.Get("Authorization")和req.Header.Get("Cookie")必须显式提取并脱敏 - 对 Authorization 值做前缀判断:
strings.HasPrefix(auth, "Bearer ")→ 掩码为"Bearer ***";strings.HasPrefix(auth, "Basic ")→ 解码后掩码用户名密码 - Cookie 字段是分号分隔的键值对,需用
http.ParseCookie解析后再逐个判断 key 是否含token、session、auth等关键词 - 脱敏后保留原始 header 结构(如
"Cookie: user=abc; token=***; theme=dark"),不删整行,便于排查
JSON 请求/响应体里的敏感字段怎么局部脱敏
不能全量 json.Unmarshal 再 json.Marshal,成本高且易丢字段;也不能字符串替换,会破坏引号、转义和嵌套结构。
- 推荐用
sjson.SetBytes对原始[]byte做局部替换,例如sjson.SetBytes(raw, "user.phone", "*** **** ***") - 支持通配:
sjson.SetBytes(raw, "users.*.password", "[REDACTED]")处理数组内所有项 - 如果已知结构体类型,更稳的方式是让结构体实现
json.Marshaler接口,用指针接收器 + 别名类型防递归 - 注意:脱敏后字节数变化会影响
Content-Length或签名验证,审计日志应记录脱敏前原始 body
如何确保所有入口都覆盖,不漏 query、form、body、header
靠单一 req.Form 或 req.URL.Query() 会漏——很多接口不用 ParseForm,或 body 是 JSON,req.Form 就是空的。
- 统一从
req.URL.RawQuery解析查询参数,它始终存在,不依赖ParseForm - POST 表单要区分编码类型:
application/x-www-form-urlencoded用req.PostForm(需先ParseForm);multipart/form-data要跳过文件字段,只处理文本 part - JSON body 必须提前
io.ReadAll(req.Body)拿到原始字节,再交给sjson或json.Unmarshal处理,不能依赖req.FormValue - 所有解析结果都进一个 map,键名标准化(如
"query.password"、"header.authorization"、"json.user.token"),再统一按敏感 key 名列表过滤
真正难的不是写脱敏逻辑,而是确保每条请求路径都走同一套解析+脱敏流程——尤其是那些绕过主中间件的 panic 日志、健康检查接口、或第三方库直发的 HTTP 调用。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










