# 数据签名 * * * * * OneBase中的数据签名安全性验证分两种,第一种是无需识别来源的数据验证(比如验证登录后的SESSION是否被修改),第二种是验证API接口数据安全性(比如客户端请求数据是否被修改,服务端返回数据是否被修改),此处来讲解一下第二种数据签名验证流程。 ![](https://box.kancloud.cn/330fad78d79204bc4ce836ff25a43438_1054x801.png) ### 服务端验证 * * * * * 先来讲一下服务端验证流程,意思就是 客户端调用接口时,服务端如何知道客户端请求的数据在请求中途是否被修改或者是否恶意模拟请求接口。 若某接口需要验证请求数据安全性,则需要启动数据签名安全验证,如下图。 ![](https://box.kancloud.cn/1a527529eb68739b30f89e90c0a1a9af_1633x344.jpg) 比如此处使用登录接口做测试,启动请求数据签名验证后,再来看看测试接口的地方。 ![](https://box.kancloud.cn/03be0e99929a73632c63cf00c8f7a5a3_703x449.jpg) 发现比之前多了一项,data_sign,这项参数是必填,也就是此接口必须有数据签名字段才能请求通过。 下面来看看 data_sign 怎么生成。 ~~~ // 过滤后的数据生成数据签名 function create_sign_filter($data = [], $key = '') { $filter_data = sign_field_filter($data); return empty($key) ? data_md5_key($filter_data, API_KEY) : data_md5_key($filter_data, $key); } ~~~ 上面这个函数就是生成data_sign的函数,能发现若不传入 key 则使用了系统自带的API_KEY 生成,这种一般用于固定的终端角色,比如 咱们的产品 只有咱们内部人员才需要请求接口,这样的话 就可以不用传递key,等开发完成后将API_KEY告知咱们的终端工程师即可。 若咱们平台做的很大,需要很多人或企业请求咱们的接口咋办? 很简单,只需要 维护 人或企业 与 key 的关联即可,这样第二个参数就派上了用场,在不同的人或企业生成数据签名时传入相关联的key。 下面来验证一下 ![](https://box.kancloud.cn/672ea34e023d2b1185f5d264ca1f2302_1475x616.jpg) 上图报了数据签名错误,因为data_sign是随便输入的。。 下面咱们生成一个签名 ~~~ $data['username'] = 'admin'; $data['password'] = '111111'; dump(data_md5_key($data, API_KEY)); // 输出结果:016fa798c3446b96521e06d46849d246 ~~~ 然后发现成功了。 ![](https://box.kancloud.cn/6e14a62352c0d3860d985a73b6abd5a8_1478x822.jpg) 若数据在请求中途被修改或者恶意模拟。。比如我将密码修改为222222 ![](https://box.kancloud.cn/389006ef777e4157573d6d836802df18_1483x617.jpg) 发现数据只要被修改后签名就提示错误,这样就可以有效的防止别人恶意请求接口,必须拿到咱们的KEY按咱们的要求生成数据签名才可以验证通过。 ### 客户端验证 * * * * * 现在需要反过来思考,服务端验证数据安全啦,那么客户端如何保证数据也是安全的? 下面来看看如何响应数据签名。 ![](https://box.kancloud.cn/5028f8707be9904646af03a7be0d24ec_1631x254.jpg) 此处选择是即可自动响应数据签名,比如登录接口启动响应数据签名后。 ![](https://box.kancloud.cn/04649d864aa8b905d060ea2011849457_1484x828.jpg) 到这一步服务端的任务已经完成了,下面就来看客户端如何表演咯。 比如下面使用PHP代码模仿客户端校验。 ~~~ $data['member_id'] = 1; $data['nickname'] = 'admin'; $data['username'] = 'admin'; $data['create_time'] = '2018-01-31 17:25:52'; dump(data_md5_key($data, API_KEY)); // 输出结果:b3bf7ba6416a3d924dab88862d4d6128 ~~~ 使用服务端返回的数据按照指定的KEY与算法进行处理后还原了数据签名,客户端需要比较自己生成的签名与服务端跟数据一起响应的数据签名是否一样,若一样则验证通过 执行后续操作,若不一样则存在安全隐患应该终止后续操作。 这就是 OneBase API模块中的数据安全性双向签名验证,保证数据安全性。^_^