1. Sentry 上报中的 beforeSend 钩子在脱敏敏感数据(PII、Token)的工程实践
在 Sentry 上报错误时,如何利用 beforeSend 钩子对 PII(如手机号、身份证号)与 Token 等敏感数据进行脱敏?脱敏应该覆盖哪些事件字段?
- beforeSend 的调用时机与返回值语义
- 敏感字段的识别策略与掩码方案
- 脱敏与采样、过滤在事件处理链中的位置
beforeSend 是 Sentry 在事件发送到服务端之前执行的同步钩子,接收完整事件对象,返回修改后的事件则继续上报,返回 null 则丢弃该事件。脱敏工程通常在这里递归遍历事件对象的 request.headers、user、contexts、extra、tags、breadcrumbs 等字段,按键名正则(如 /(token|password|phone|idcard)/i)或值格式匹配敏感内容,替换为 **** 掩码或哈希值。由于前端事件一旦上传,服务端 DSN 通道内的数据便难以回退,因此脱敏必须前置到客户端钩子中完成。此外还应结合环境判断,在生产环境强制启用脱敏、开发环境保留完整上下文,并避免在 beforeSend 中执行耗时或异步逻辑,防止阻塞上报。
本题考察对错误上报生命周期钩子的理解。beforeSend 处于"事件已组装、尚未传输"的最后一环,是统一治理敏感数据的唯一可靠位置;回答时需点明返回 null 的双重用途(丢弃噪声与丢弃含密事件),并覆盖 PII 与 Token 两类典型的脱敏对象,体现生产环境的工程完备性。
Sentry.init({
dsn: '...',
beforeSend(event) {
const MASK_KEYS = /(token|password|secret|phone|idcard|authorization)/i;
const mask = (obj) => {
if (!obj || typeof obj !== 'object') return;
Object.keys(obj).forEach((k) => {
if (MASK_KEYS.test(k)) obj[k] = '****';
else if (typeof obj[k] === 'object') mask(obj[k]);
});
};
mask(event.request);
mask(event.contexts);
mask(event.extra);
return event;
},
});