今天正好看到一篇关于敏感信息过滤的文章,这算做一个interface实际应用的一些举例和应用。
例子中介绍了一种比较常见的使用场景:使用JSON保存数据时的对诸如用户密码等信息进行保护时候应该做的事情。作者以使用JSON格式保存用户账户和密码为例,讲解了使用json.Unmarshaler
接口类型过滤敏感信息。
比如,对于保存敏感数据的结构体:
1 | type Credentials struct { |
通过定义MarshalJSON
方法满足json.Unmarshaler
接口类型的要求,这样,当使用json.Unmarshal
等方法时,就可以规避掉在日志或者JSON接口之类的方法中输出敏感信息Password
。
文中提及了json.Unmarshaler
接口一个方法,但这种方法并不是完全能够解决所有的类型的敏感信息过滤问题。比如在使用调试过程中,开发人员常常使用的fmt/log
包,则不能用这种方法解决。
要解决这个问题,则需要使用另外一个值得注意的接口类型,那么就是fmt.Stringer
接口类型。该接口类型通常用于如log/fmt
之类的包的输出中。
实际上,我个人认为非常合适的方法是,我们可以特定某个特殊类型Sensitivity
,对于敏感信息统一采用这个类型予以保护。这样也方便我们后续添加新的保护方式。
看一下这个敏感信息如何过滤:
1 | type Sensitivity string |
输出结果为:
1 | request: {{bilbro@theshire.net [SENSITIVE DATA]}} |
同样的,我们结合第一个方法中的json.Unmarshaler
一起使用时,那么就是一个比较完整的敏感信息过滤方案了。
1 | type Sensitivity string |
这种方式也能很好的兼容各种数据库ORM库,保证我们的功能可以正常应用在数据模型等场景上:
1 | sess, _ := mgo.Dial("") |
类似的还有一个涉及编码方法encoding.TextMarshaler
,基本与fmt.Stringer
类似,因此也不需要额外的赘述了。
注意:如果你使用了如fmt.Sprintf之类的格式化请求,也会受到fmt.Stringer
接口类型的影响,请根据使用情况酌情使用。