0.3.2 • Published 4 years ago
lightning-base v0.3.2
旨在解放小型应用的后端工作量
基于 fastify
的 serverless
serverless
const lightning = require('lightning-base');
const start = async () => {
await lightning.db.init('mongodb://127.0.0.1:27017');
// 开发过程中可以取消跨域检测,注意不要在生产中使用
lightning.setCors();
// 启动 serverless 服务
lightning.serverless({
url: '/less',
// 若设定,会限定每个请求体的有效时间,此例子为前后不超过15分钟
checkTime: 1000 * 60 * 15,
// 若设定,会校验一个key,只有key正确时才有权限操作
checkKey: '123456',
// 拦截某些数据库的操作
blockDb: ['user'],
// 拦截某些表的操作
blockCol: ['pay'],
// 针对某些表的一些限制, 提高安全性
impose: {
user: {
// 更新、删除某些表的内容时,操作必须添加的 filter
filter: [['$eq.user', '$eq.password'], '$eq:token'],
// 移除user表查询之后返回的数据
remove: ['ops.0.password'],
},
},
// 开启 RSA 加密,自动配置RSA加密方案, 此密钥请设置较长且保留好
// 若前后端要更新 RSA 密钥,请更新这个密钥,并且重启服务器
// 开启 autoRSA,之后,可以通过访问服务 /lightning/rsa?name=the-password 拿到客户端密钥,此服务若失败5次,需要间隔1小时方可尝试
autoRSA: 'the-password',
});
try {
await lightning.app.listen(4010, '0.0.0.0');
} catch (error) {
lightning.app.log.error(error);
process.exit(1);
}
};
start();
设置了 serverless 之后,大部分 mongodb 数据库的操作都迁移到了前端, client 请求。
我们以开启了 autoRSA 加密方案为例,首先启动服务,然后访问以下链接拿到 client 的 RSA 密钥:
http://0.0.0.0:4010/lightning/rsa?name=the-password
接下来先为客户端创建一个请求方法 client:
const Axios = require('axios').default;
const NodeRSA = require('node-rsa');
const decode = new NodeRSA({ b: 512 });
decode.setOptions({ encryptionScheme: 'pkcs1' });
decode.importKey(
`
-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAI9UlD+q0TEPH2U2wLHM6Pl+kwadrHxS
gMBr9IaLNwg3etHbzKktJ/tpKxtygOUm9F1+bmJOQvkamQpPYql/P+kCAwEAAQ==
-----END PUBLIC KEY-----
`,
'public',
);
const encode = new NodeRSA({ b: 512 });
encode.setOptions({ encryptionScheme: 'pkcs1' });
encode.importKey(
`
-----BEGIN RSA PRIVATE KEY-----
MIIBPAIBAAJBAM0weU8cwkKXu0+VG+7L5KJkX3ePIdfva6LL4uF06YeR9YrTGHhd
5/sS7M81MfFzYylLCqO94RJNtgih8MT/essCAwEAAQJAeUAGv0goRv+wkTN0oSTd
Q1T60QTEo/x352iB9maGxTPcLZuM3NwwcwtKN4cZ9aL53Y9SMpYdCjpx67NWcx2S
oQIhAPpmH1s+kL1wTPnl6QXcoXoiVnZh2oFc/nfq2z4CM6fxAiEA0cd27V3OzAFs
saDiqShwoqE2wCaf+8pH805EpsDkansCIQCWg4BhtpAGb1S1+k9B6MdfxPg4HMXd
cOq9Znz3Hxex4QIhAIjDR498huONUjWDtAGgMb505+Lhy4810y6WKj+kpcWdAiEA
8XJBxFjhQuE28aRbV+fVuiHQX1LHOu2FPGc2BewB/eQ=
-----END RSA PRIVATE KEY-----
`,
'private',
);
const client = async data => {
return new Promise(cb => {
Axios.post(
'http://127.0.0.1:4010/less',
{ code: encode.encryptPrivate({ ...data, _checkTime: Date.now(), _checkKey: '123456' }, 'base64') },
{
headers: { 'content-type': 'application/json' },
},
)
.then(res => {
if (res.data) {
if (res.data.code) {
return cb(decode.decryptPublic(res.data.code, 'utf8'));
}
return cb(res.data);
}
return res;
})
.catch(err => cb(err.response ? err.response.data : err));
});
};
客户端操作数据库,暂时仅支持以下方法:
- insert
- insertMany
- insertOne
- deleteOne
- update
- updateMany
- updateOne
- replaceOne
- find
- findOne
接下来,我们从客户端发起请求,操作数据库,服务端执行 db.collectionmethod:
client({
db: 'test',
col: 'anima',
method: 'insertOne',
args: [{ name: 'dog', age: '11', createAt: Date.now() }],
}).then(res => {
console.log(res.data);
});
// 我们还可以描述哪些字段存表之前,在后端使用sha256加密,或将字段转为ObjectId:
client({
db: 'test',
col: 'user',
method: 'insertOne',
argsSha256: ['0.password'], // 调整字段:args[0][password]
argsObjectId: ['0._id'], // 调整字段:args[0][_id]
args: [{ _id: '5df3d87143234867f3626f2f', username: 'dog', password: 'bbb', createAt: Date.now() }],
}).then(res => {
console.log(res.data);
});
// 我们看到,创建之后,整个对象也返回了,我们为了节流,可以屏蔽ops:
client({
db: 'test',
col: 'user',
method: 'insertOne',
argsSha256: ['0.password'], // 调整字段:args[0][password]
argsObjectId: ['0._id'], // 调整字段:args[0][_id]
args: [{ _id: '5df3d87143234867f3626f2f', username: 'dog', password: 'bbb', createAt: Date.now() }],
// 删除返回值的 ops[0] 字段, 注意,前端设置 remove 仅适合减少数据流量,如要提高数据安全性,请在后端设置 impose.remove
remove: ['ops.0'],
}).then(res => {
console.log(res.data);
});
// 更新操作:
client({
db: 'test',
col: 'user',
method: 'updateOne',
// 若在服务端设置了 impose.user, 其中描述了必须声明对 user 表的操作必须校验 username 和 password
args: [{ username: { $eq: 'dog' }, password: { $eq: 'bbb' } }, { $set: { money: 100, updateAt: Date.now() } }],
trim: ['ops.0.password'],
}).then(res => {
console.log(res.data);
});
// 删除操作:
client({
db: 'test',
col: 'user',
method: 'deleteOne',
// 若在服务端设置了 impose.user, 其中描述了必须声明对 user 表的操作必须校验 username 和 password
args: [{ username: { $eq: 'dog' }, password: { $eq: 'bbb' } }],
}).then(res => {
console.log(res.data);
});
以上示例演示了如何在客户端直接创建、修改、删除数据库的操作,并且演示了如何约定校验\剔除数据、添加非对称加密,以提高一部分安全性。
普通服务
lightning-base 亦可以快速搭建普通的 web 服务:
const lightning = require('lightning-base');
const start = async () => {
await lightning.db.init('mongodb://127.0.0.1:27017');
// 开发过程中可以取消跨域检测
lightning.setCors();
// 自动加载文件名包含 .controller.js 的文件
lightning.controllersLoader(resolve(__dirname, './controllers'), '.controller.js');
lightning.app.get('/ping', (req, rep) => {
rep.send({ hello: 'world' });
});
lightning.app.post('/ping', (req, rep) => {
let { username, password } = req.body || {};
rep.send({ hello: `${username}-${password}` });
});
try {
await lightning.app.listen(4010, '0.0.0.0');
} catch (error) {
lightning.app.log.error(error);
process.exit(1);
}
};
start();
0.3.2
4 years ago
0.3.1
4 years ago
0.3.0
4 years ago
0.2.10
4 years ago
0.2.7
4 years ago
0.2.9
4 years ago
0.2.8
4 years ago
0.2.5
4 years ago
0.2.4
4 years ago
0.2.3
4 years ago
0.2.1
4 years ago
0.2.2
4 years ago
0.1.14
4 years ago
0.1.15
4 years ago
0.2.0
4 years ago
0.1.11
4 years ago
0.1.12
4 years ago
0.1.13
4 years ago
0.1.10
4 years ago
0.1.9
4 years ago
0.1.8
4 years ago
0.1.6
4 years ago
0.1.5
4 years ago
0.1.4
4 years ago
0.1.2
4 years ago
0.1.1
4 years ago
0.1.3
4 years ago
0.1.0
4 years ago