背景
随着互联网越来越深入我们的生活,个人生活方方面面都离不开互联网了,我们在使用互联网产品的时候,不免会在互联网平台授权一些个人信息,如果互联网平台没有做好这方面的把控,我们的个人信息信息就很有可能泄露给不法分子,损害了我们的隐私安全。
好友阿杰的公司对个人信息的保护也很重视,阿杰就接手了一个对他们公司后台管理系统中展示的个人信息进行脱敏的需求,所有原先明文展示用户信息的地方,都要做数据脱敏。比如,
姓名:张阿三,需要改为为:张*三。
身份证:123456789012345678,需要改为123******78。
手机号:12356789000,需要改为:123****9000。
类似这样,其他的一些地址之类的其他个人信息也需要脱敏。
目前后台系统中也有一些已经做了信息脱敏的,阿杰准备看一些别人的代码,抄一下,毕竟能复制的绝不手写,这样才能提高效率。
不看不知道,一看吓一跳,光一个脱敏的方法,系统中就有五六个个不一样的方法。
有人直接用在接口返回的数据中进行字符串替换
<?php
foreach ($arr as &$value) {
$value['phone'] = substr($data, 0, 3) . '****' . substr($data, 7);
}
有人封装了一个脱敏方法,也是直接用字符串替换
<?php
class DataMasking
{
// 伪代码 非真实实现逻辑
public function mask($data, $num1, $num2)
{
return substr($data, 0, $num1) . '****' . substr($data, $num1);
}
}
还有一个字符串匹配的方法类似StringHelper::HideStr()的调用。
还有一个手机号脱敏的字符串类似StringHelper::HidePhone()的调用。
还有......
天呐,这都是什么跟什么,太乱了吧,后续代码如何维护,如果扩展,这简直就是灾难。试想一下,有这么多方法,逻辑不同,脱敏规则也不同,如果有要求要修改为统一的脱敏规则,工作量得有多大,特别是像那种愚蠢的直接在接口返回数据中用字符串替换来修改的,真的是愚不可及。
优化
阿杰分析了下这个需求,觉得需要封装一个脱敏类,对不同的敏感信息提供不同的脱敏方法(单一职责)。而且为了防止后续脱敏规则有变化,需要提供一层抽象(接口隔离)。
代码大概是这样的:
<?php
// 声明一个'DataMasking'接口
interface DataMasking
{
public function mask($data);
}
// 实现接口
class PhoneMasking implements DataMasking
{
public function mask($data)
{
return substr($data, 0, 3) . '****' . substr($data, 7);
}
}
// 脱敏方法
class DataMasking
{
public $data;
public function __construct($data)
{
$this->data = $data;
}
public function mask(DataMasking $obj)
{
$this->data = $$obj->mask($this->data);
}
public function phoneMask()
{
$this->mask(new PhoneMasking())
return $this->data;
}
}
反思
首先,一个项目中代码如此的混乱,说明没有严格的代码审核,时间久了,后续审核代码的人换了,接手的人更不知道已经有了哪些方法。也说明这家公司没有有效的项目管理,也没有技术积累,由此可见一斑,项目中肯定有不少类似这样的情况,严重的背离了DRY原则。重复往往意味着低效,意味着更高的开发和维护成本,间接的也影响到了公司的效益。
对于这种情况,我觉得行之有效的办法就是维护一份组织良好的开发文档,别人在开发新功能需要用到一些方法时,先要查询开发文档中是不是已经有类似的方法了,如果没有就新增,并及时更新到文档中。
代码审阅的人尤其要熟悉这份文档,在审阅时要注意开发人员编写的代码是否有重复造轮子的情况。公司新人入职也要先熟悉这份文档再开发。这样便可以最大程度的降低代码复用率低的情况,提升开发效率与质量。
手册具体如何书写,我的建议是务必保持手册的整洁性,其他业务描述类的文档不要掺杂进去。手册也要便于查看,不要想找的时候,找了半天也找不到。可以采用语雀文档,markdown文档,在线网页等形式来呈现,如果文档内容质量较高,也没有涉及敏感数据和信息,甚至可以共享到github。
手册的内容也要保持清晰,建立良好的目录,文档进行合理的划分。
评论区