原文作者:ipfans
今天正好看到一篇关于敏感信息过滤的文章,这算做一个interface实际应用的一些举例和应用。
例子中介绍了一种比较常见的使用场景:使用JSON保存数据时的对诸如用户密码等信息进行保护时候应该做的事情。作者以使用JSON格式保存用户账户和密码为例,讲解了使用json.Unmarshaler
接口类型过滤敏感信息。
比如,对于保存敏感数据的结构体:
1type Credentials struct {
2 Email string `json:”email”`
3 Password string `json:”password”`
4}
5func (co Credentials) MarshalJSON() ([]byte, error) {
6 type credentials Credentials
7 cn := credentials(co)
8 cn.Password = "[REDACTED]"
9 return json.Marshal((*credentials)(&cn))
10}
通过定义MarshalJSON
方法满足json.Unmarshaler
接口类型的要求,这样,当使用json.Unmarshal
等方法时,就可以规避掉在日志或者JSON接口之类的方法中输出敏感信息Password
。
文中提及了json.Unmarshaler
接口一个方法,但这种方法并不是完全能够解决所有的类型的敏感信息过滤问题。比如在使用调试过程中,开发人员常常使用的fmt/log
包,则不能用这种方法解决。
要解决这个问题,则需要使用另外一个值得注意的接口类型,那么就是fmt.Stringer
接口类型。该接口类型通常用于如log/fmt
之类的包的输出中。
实际上,我个人认为非常合适的方法是,我们可以特定某个特殊类型Sensitivity
,对于敏感信息统一采用这个类型予以保护。这样也方便我们后续添加新的保护方式。
看一下这个敏感信息如何过滤:
1type Sensitivity string
2func (s Sensitivity) String() string {
3 return "[SENSITIVE DATA]"
4}
5...
6 request := CreateUserRequest{
7 Credentials: Credentials{
8 Email: "bilbro@theshire.net",
9 Password: "theonering",
10 },
11 }
12 fmt.Println("request:", request)
输出结果为:
1request: {{bilbro@theshire.net [SENSITIVE DATA]}}
同样的,我们结合第一个方法中的json.Unmarshaler
一起使用时,那么就是一个比较完整的敏感信息过滤方案了。
1type Sensitivity string
2func (s Sensitivity) String() string {
3 return "[SENSITIVE DATA]"
4}
5func (s Sensitivity) MarshalJSON() ([]byte, error) {
6 return []byte(`"[SENSITIVE DATA]"`), nil
7}
这种方式也能很好的兼容各种数据库ORM库,保证我们的功能可以正常应用在数据模型等场景上:
sess, _ := mgo.Dial("")
sess.DB("test").C("data").Insert(&request.Credentials)
var c Credentials
sess.DB("test").C("data").Find(bson.M{}).One(&c)
fmt.Println(c.Password == "theonering")
...
db, _ := gorm.Open("mysql", "root:pwd@/ytest?charset=utf8&parseTime=True&loc=Local")
...
db.Create(&request.Credentials)
var c Credentials
db.First(&c)
fmt.Println(c.Password == "theonering")
类似的还有一个涉及编码方法encoding.TextMarshaler
,基本与fmt.Stringer
类似,因此也不需要额外的赘述了。
注意:如果你使用了如fmt.Sprintf之类的格式化请求,也会受到fmt.Stringer
接口类型的影响,请根据使用情况酌情使用。
版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢。