https://github.com/WangShan010/CesiumNetworkPlug
关键词:Cesium、IndexDB、Data Encryption、浏览器缓存、网络传输、数据加密
## 一、项目简介
**CesiumNetworkPlug.js** 是一个为 Cesium 开发的 **数据传输功能** 拓展插件,具备以下两个核心功能
### 1、浏览器缓存
模块名:OfflineCacheController
简介:增加对浏览器本地缓存的支持,它使用 **indexDB** 离线缓存技术管理 影像图层、地形、3DTiles模型 等资源数据。
原理:在 Cesium 发送 **资源请求**(图层、地形、模型)前,判断本地是否有缓存存在,如果存在则优先使用本地缓存,本地缓存策略能 **极大提升** 场景的二次加载速度。
### 2、数据加密
模块名:DecryptionController
背景:部署在公网的云服务器的 Cesium WebGIS 项目时常面临着严重的数据安全威胁。如果没有做好安全措施,不怀好意的第三方开发者只需要写一个简单的爬虫,就能把 Web 服务器中的 **3DTiles**、**高精度影像图层**、**地形数据**、**矢量数据** 等静态资源全部 Download 走!
简介:配合服务端的 Cesium 数据加密传输的插件,将静态资源数据在服务端通过加密算法生成为加密格式,再传输给客户端;前端根据密码自动解密复为原始数据。
原理:如需要使用本功能,需要按以下两个步骤进行操作
- NodeJs 服务端
本仓库提供了用于数据加密的库,可在 Web服务器中将数据加密后返回 http 请求,示例代码可看下文
- 浏览器端
引入后,配置好密码即可自动用于对资源路径请求进行代理,并解密。
## 二、使用方式
### 1、链接地址
- 在线体验:http://101.43.223.126:5000/
- 插件下载
- 完整包:http://101.43.223.126:5000/CesiumNetworkPlug/dist/CesiumNetworkPlug.min.js
- 加解密函数库:http://101.43.223.126:5000/CesiumNetworkPlug/dist/CryptoUtil.min.js
- 离线 Demo下载:http://101.43.223.126:5000/Release.rar
### 2、Web 端
引入插件:
```html
```
### 3、NodeJS 服务端
> 注意!服务端的运行环境必须是 **NodeJS V18.0** 以上
```js
const fs = require("fs");
const path = require("path");
const CryptoUtil = require("./lib/CesiumNetworkPlug/dist/CryptoUtil.min.js");
async function test() {
const fileName = "浙江省.geojson";
const buffer = fs.readFileSync(path.join(__dirname, "../www/" + fileName));
const blob = new Blob([buffer]);
const [encryptErr, encryptBlob] = await CryptoUtil.encryptByBlob(blob, "@mtJQGyEEq6DBK.hxVR*3fTGgXssxCfMtZQEyUTF", fileName, false);
const encryptBuffer = Buffer.from(await encryptBlob.arrayBuffer());
fs.writeFileSync(path.join(__dirname, fileName), encryptBuffer);
}
```
## 三、API 文档
命名空间:`window.CesiumNetworkPlug.*`
- **CesiumNetworkPlug**
```js
const CesiumNetworkPlug = {
DecryptionController,
OfflineCacheController,
CryptoUtil: DecryptionController.CryptoUtil
};
```
- DecryptionController(Web端解密规则控制器)
```js
const DecryptionController = {
ruleMap: new Map(),
// 判断该资源项是否需要解密
judgeUrl(judgeUrl:string) {
return {needDecode:boolean, decodePassword:string};
},
CryptoUtil:CryptoUtil
};
```
- **OfflineCacheController**(Web端数据缓存规则控制器)
```js
const OfflineCacheController = {
// 缓存规则
ruleList: new Set(),
// 判断该资源项是否符合缓存规则
judgeUrl(url) {},
async keys() {},
async clear() {},
// 计算缓存占用的存储空间大小
async getUseSize() {}
};
```
- **CryptoUtil(加密、解密工具类)**
```js
const CryptoUtil = {
async encryptByBlob(blob, password, fileName, debug = false) {
return [encryptedErr, encryptedBlob];
},
async decryptByBlob(blob, password, debug = false) {
return [encryptedErr, encryptedBlob];
},
async decryptByUrl(url, password, debug = false) {
return [encryptedErr, encryptedBlob];
},
async decryptFirstFileBlob(encryptedBlob, password, debug = false) {
return [decryptedErr, blob];
},
async decryptFirstFileByUrl(url, password, debug = false) {{
return [decryptedErr, blob];
},
async blobToText(blob) {
return [err, text];
},
async blobToJson(blob) {
return [err, json];
},
async blobToArrayBuffer(blob) {
return blob.arrayBuffer();
}
};
```
## 四、拓展说明:数据安全
业界主流主要是采用以下几种方案,这几个方案可进行组合使用:
### 1、拒绝跨域访问
安全性::star:
数据直接放在Web服务器下,拒绝跨域访问资源。
- 缺点:这个安全性最低!第三方程序员只需要写一个请求转发的后端程序,就能直接盗用资源数据。
### 2、携带资源访问令牌
安全性::star::star:
这个是绝大部分在线地图商采用的方案,服务端要求客户端在请求头中携带资源访问令牌,即 Token ,并允许跨域访问。
- 缺点:Token 极易泄露!例如 天地图影像、MapBox影像、Ceisum 官方地形数据,都采用的这种方式,开发者者打开浏览器控制台,盗走 Token 轻而易举。
### 3、资源访问权限拦截
安全性::star::star::star:
检查当前用户是否登录,如果为未登录则拒绝资源请求 URL。
例如:开发后台服务程序,使用 Session 会话机制检查当前用户是否登录,如果为未登录则拒绝资源请求 URL。该方案实际上是检查资源请求头中的 Session ID,能灵活对用户账号的权限做判断,**安全性有明显提升**。
- 缺点:
- 但如果攻击者有业务系统的合法账号,数据仍有被爬虫盗取的可能。
- 需要编写的后台服务的代码量比较大。
- 这个方案与 Token 的 HTTP 无状态设计理念相悖
### 4、定义一套数据交互格式
安全性::star::star::star::star::star:
一劳永逸法!自己创建一套数据格式,并写数据解析库来支持数据上球。
缺点:
- 开发量非常大,并且数据接口无法共享
## 五、其他说明
作者 QQ:2394837320
模块内置授权模块,试用期到 2023年09月1日
**Q&A**
1. 这个插件收费吗?
回答:使用不收费,可以联系作者买源码。
里面写了日期的许可,但代码仅仅做了压缩,没有做混淆加密。~~如果你执意要白嫖,那么没关系,找到代码里许可的位置,移除掉它就行。~~
2. 使用了 indexDB,页面加载速度就一定会提升吗?
回答:不一定!只有三维倾斜模型资源的体积比较大,且网络带宽低于 5M 时才会有明显的提升。
3. 数据加密模块是怎么使用的?
回答:可看示例代码,这里有写了如何对数据进行加密、解密。
而在项目中使用,需要对数据进行提前加密,否则服务器负担会较大。
4. 使用了数据加密模块后,性能如何页面载入会变慢吗?
回答:会有轻微的影响!对 1Mb 的文件进行解密,耗时约为 100ms。
最佳实践:
- 数据可预先加密好,将资源包放到 https://github.com/WangShan010/SQLiteFileMana
- 数据加密模块配合数据缓存模块使用,二次加载的体验会有很大的提升
5. 这是怎么加密的,会不会存在安全问题?
回答:用的是 AES 算法,至于安全性嘛,按目前地球的科技还是没办法破解的。
6. 我调试 OfflineCacheController 缓存模块的时候,好像出 bug 了怎么清空缓存?
回答:打开控制台=>存储=>indexed DB 右键清空,或者在控制台输入指令:```CesiumNetworkPlug.OfflineCacheController.clear()```
7. 加密服务和前端插件都配置好了,我怎么知道我的数据已经被加密好了了?
回答:很简单,用 FireFox 浏览器打开控制台=>网络请求,查看 Cesium 发出的请求,比如图层图片、3DTiles、geojson 等,你会发现返回类型是一个很奇怪的格式【crypto-blob】,并且是 UEsDBDMACQhj 开头的一个二进制流。
这个数据可以通过 CesiumNetworkPlug 插件,根据密码进行自动解密。
即便别人把数据爬走也不可使用!
