如何在gqlgen中对敏感请求参数进行掩码处理?
处理gqlgen请求参数敏感信息的掩码方案
下面是几种实用的敏感参数掩码方案,可根据项目需求选择:
1. 硬编码敏感字段掩码(快速实现)
直接指定需要掩码的字段名,遍历请求变量并替换敏感内容,适合字段数量少、变动少的场景。
实现代码:
// 定义敏感字段处理函数 func maskSensitiveVariables(vars map[string]interface{}) map[string]interface{} { maskedVars := make(map[string]interface{}) // 配置需要掩码的字段 sensitiveKeys := map[string]bool{ "password": true, "email": true, "phone": true, } for key, val := range vars { if sensitiveKeys[key] { // 根据字段类型做不同掩码处理 switch value := val.(type) { case string: if len(value) >= 3 { maskedVars[key] = value[:3] + "***" // 保留前3位,其余替换为*** } else { maskedVars[key] = "***" } default: maskedVars[key] = "***" // 非字符串类型直接替换为*** } } else { maskedVars[key] = val // 非敏感字段原样保留 } } return maskedVars } // 在ErrorPresenter中使用 srv.SetErrorPresenter(func(ctx context.Context, err error) *gqlerror.Error { goc := graphql.GetOperationContext(ctx) // 对变量进行掩码处理后再记录 maskedVars := maskSensitiveVariables(goc.Variables) fmt.Println("请求参数(已掩码):", maskedVars) gqlErr := graphql.DefaultErrorPresenter(ctx, err) return gqlErr })
2. 基于Schema标记的动态掩码(扩展性强)
在GraphQL Schema中用自定义指令标记敏感字段,启动时解析Schema收集敏感字段列表,无需硬编码字段名,适合大型项目。
步骤1:在Schema中添加敏感字段指令
# 定义敏感字段指令 directive @sensitive on INPUT_FIELD_DEFINITION # 示例输入类型,标记敏感字段 input LoginInput { email: String! @sensitive password: String! @sensitive } input UserUpdateInput { nickname: String phone: String! @sensitive }
步骤2:解析Schema收集敏感字段
import ( "github.com/99designs/gqlgen/graphql/astparser" "github.com/vektah/gqlparser/v2/ast" ) var sensitiveFieldSet = make(map[string]bool) func init() { // 加载并解析本地Schema文件 schemaDoc, err := astparser.ParseFiles("./schema.graphqls") if err != nil { panic("解析Schema失败:" + err.Error()) } // 遍历所有输入对象字段,收集带@sensitive标记的字段名 for _, def := range schemaDoc.Definitions { if def.Kind == ast.DefinitionKindInputObject { for _, field := range def.Fields { for _, dir := range field.Directives { if dir.Name == "sensitive" { sensitiveFieldSet[field.Name] = true } } } } } }
步骤3:复用掩码函数处理变量
把第一种方案中的sensitiveKeys替换成sensitiveFieldSet即可,后续新增敏感字段只需在Schema中标记,无需修改代码。
3. 前置变量解析时掩码(更安全)
在GraphQL变量解析阶段就完成敏感信息掩码,避免敏感数据在中间流程中泄露,适合对安全性要求极高的场景。
实现思路:
通过gqlgen的自定义UnmarshalFunc,对标记为敏感的字段类型进行特殊处理。例如定义一个SensitiveString类型,重写其序列化/反序列化逻辑:
type SensitiveString string // 反序列化时保留原始值(业务逻辑需要) func (s *SensitiveString) UnmarshalGQL(v interface{}) error { str, ok := v.(string) if !ok { return fmt.Errorf("敏感字段必须为字符串类型") } *s = SensitiveString(str) return nil } // 序列化(记录日志时)返回掩码后的值 func (s SensitiveString) String() string { str := string(s) if len(str) >= 3 { return str[:3] + "***" } return "***" }
在Schema中使用该类型:
scalar SensitiveString input LoginInput { email: SensitiveString! password: SensitiveString! }
生成代码后配置自定义标量:
在gqlgen.yml中添加标量映射:
models: SensitiveString: model: github.com/your-project/pkg/types.SensitiveString
这样在记录变量时,直接打印SensitiveString类型的值就会输出掩码后的内容,业务逻辑中仍可获取原始值。
内容的提问来源于stack exchange,提问作者anderson
相关产品推荐
相关产品推荐

