使用gqlgen与ent时,如何避免GraphQL暴露哈希密码字段?
问题解答:Ent+Gqlgen隐藏GraphQL敏感字段
返回空值的方式是否可行?
这种方式不可行,也不推荐。虽然Resolver返回空值后客户端拿不到敏感数据,但GraphQL Schema里依然保留hassPassword字段,客户端在Playground或Schema文档里能看到这个字段的存在,容易造成混淆,甚至可能引发不必要的请求。而且这不符合GraphQL的设计原则——Schema应该精准反映对外暴露的可用字段。
完全隐藏字段的几种方法
针对Ent+Gqlgen的组合,有以下几种可靠的实现方式:
1. 在Ent Schema中添加排除标签
直接在Ent的实体定义里,给敏感字段加上gqlgen:"-"标签,让Gqlgen生成Schema时自动忽略该字段。同时可以加上Ent的Sensible()标签,让Ent在生成CRUD接口时也隐藏这个字段:
// ent/schema/user.go func (User) Fields() []ent.Field { return []ent.Field{ field.Int64("id"), field.String("user_name").Unique(), // 关键配置:gqlgen:"-" 排除出GraphQL Schema,Sensible()标记为敏感字段 field.String("hass_password").Sensible().Tag("gqlgen:\"-\""), field.String("email").Unique(), } }
修改后重新执行go generate ./ent和Gqlgen的生成命令,新的Schema里就不会有hassPassword字段了。
2. 通过Gqlgen配置文件排除字段
如果不想修改Ent的Schema,可以在gqlgen.yml里配置模型字段的跳过规则:
# gqlgen.yml models: User: fields: hassPassword: skip: true
保存后重新生成Gqlgen代码,生成的GraphQL Schema会自动移除该字段。
3. 使用DTO(数据传输对象)做层转换
定义一个只包含对外暴露字段的DTO结构体,在Resolver层把Ent的User模型转换成DTO返回:
// 定义GraphQL专用的DTO type UserDTO struct { ID int64 `json:"id"` UserName string `json:"userName"` Email string `json:"email"` } // Resolver中实现转换逻辑 func (r *userResolver) User(ctx context.Context, id int64) (*UserDTO, error) { user, err := r.client.User.Get(ctx, id) if err != nil { return nil, err } // 只返回需要暴露的字段 return &UserDTO{ ID: user.ID, UserName: user.UserName, Email: user.Email, }, nil }
同时在gqlgen.yml里把GraphQL的User类型映射到这个DTO:
# gqlgen.yml models: User: model: your-project/pkg/graphql.UserDTO # 替换成你的DTO路径
这种方式灵活性最高,适合需要对返回数据做更多定制(比如字段重命名、组合数据)的场景。
内容的提问来源于stack exchange,提问作者talpx
相关产品推荐
相关产品推荐

