介绍
`database-proxy` 是一个「超级API」,一个 API 替代服务端 90% 的传统 APIs。
通过一套「访问控制规则」配置数据库访问,让前端开发者“安全直连”数据库,再也不需要和服务端对接口了!
客户端使用 `laf-client-sdk` ,像在服务端操作数据库那样,在客户端直接读写相应的数据即可。
使用
npm install database-proxy
服务端代码示例
const app = require('express')()
const { Proxy, MongoAccessor, Policy } = require('database-proxy')
app.use(express.json())
const rules = {
categories: {
"read": true,
"update": "!uid",
"add": "!uid",
"remove": "!uid"
}
}
const accessor = new MongoAccessor('mydb', 'mongodb://localhost:27017', { directConnection: true })
accessor.init()
const policy = new Policy(accessor)
policy.load(rules)
const proxy = new Proxy(accessor, policy)
app.post('/proxy', async (req, res) => {
const { uid } = parseToken(req.headers['authorization'])
const injections = {
uid: uid
}
const params = proxy.parseParams(req.body)
const result = await proxy.validate(params, injections)
if (result.errors) {
return res.send({
code: 1,
error: result.errors
})
}
const data = await proxy.execute(params)
return res.send({
code: 0,
data
})
})
app.listen(8080, () => console.log('listening on 8080'))
客户端使用
npm install laf-client-sdk
const cloud = require('laf-client-sdk').init({
dbProxyUrl: 'http://localhost:8080/proxy',
getAccessToken: () => localStorage.getItem('access_token')
})
const db = cloud.database()
const res = await db.collection('categories').get()
const res = await db.collection('articles')
.where({status: 'published'})
.orderBy({createdAt: 'asc'})
.offset(0)
.limit(20)
.get()
const res = await db.collection('articles')
.doc('the-doc-id').update({
title: 'new-title'
})
更多使用参考客户端使用文档
数据访问安全规则示例
简单示例 1:简单博客
{
"categories": {
"read": true,
"update": "$admin === true",
"add": "$admin === true",
"remove": "$admin === true"
},
"articles": {
"read": true,
"update": "$admin === true",
"add": "$admin === true",
"remove": "$admin === true"
}
}
简单示例 2:多用户博客
{
"articles": {
"read": true,
"update": "$userid && $userid === query.createdBy",
"add": "$userid && data.createdBy === $userid",
"remove": "$userid === query.createBy || $admin === true"
}
}
复杂示例 1: 数据验证
{
"articles": {
"add": {
"condition": "$userid && data.createdBy === $userid"
},
"remove": "$userid === query.createBy || $admin === true",
"$schema": {
"title": {"length": [1, 64], "required": true},
"content": {"length": [1, 4096]},
"like": { "number": [0,], "default": 0}
}
}
}
复杂示例 2:更高级的数据验证
场景介绍: 用户之间站内消息表访问规则
{
"messages": {
"read": "$userid && ($userid === query.receiver || $userid === query.sender)",
"update": {
"condition": "$userid && $userid === query.receiver",
"data": {
"read": {"in": [true]}
}
},
"add": {
"condition": "$userid && $userid === data.sender",
"data": {
"read": {"in": [false]}
}
},
"remove": false,
"$schema": {
"content": {"length": [1, 20480], "required": true},
"receiver": {"exists": "/users/id"},
"read": { "in": [true, false], "default": false }
}
}
}
运行测试
安装依赖
npm i
单元测试
npx mocha tests/units/*.test.js
数据库访问测试
Mongo
使用 Docker 启动个测试数据库,等待mongo 启动成功
docker pull mongo
docker run --rm -p 27018:27017 --name mongotest -d mongo
执行测试用例
npx mocha tests/mongo_db/*.test.js
停止&删除 Mongo 实例
docker rm -f mongotest
MySQL
使用 Docker 启动个测试数据库,等待mongo 启动成功
docker pull mysql
docker run --name mysqltest -e MYSQL_ROOT_PASSWORD=kissme -e MYSQL_DATABASE=testdb -d -p 3306:3306 mysql
手动创建测试使用的数据表:
create table IF NOT EXISTS categories (
id int not null auto_increment,
name varchar(64) not null,
created_at int,
primary key(id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
create table IF NOT EXISTS articles (
id int not null auto_increment,
title varchar(64) not null,
category_id int,
content text,
created_at int,
updated_at int,
created_by int,
primary key(id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
执行测试用例
npx mocha tests/mysql_db/*.test.js
停止&删除 Mongo 实例
docker rm -f mysqltest
执行所有测试用例
请确保已经运行 mongo 和 mysql 测试的实例;
npx mocha tests/**/*.test.js
1.0.0-beta.12 (2023-10-31)
Bug Fixes
- cli: fix app init error (#1608) (7788d6c)
- cli: fix update func bug (#1610) (92c9830)
- cli: storage server api changed for cli (#1609) (bf4150e)
- deploy: minio console ingress enable websocket (#1555) (f360709)
- gateway: fix cors headers conf of runtime, ingress nginx installation (#1565) (8de0a29)
- runtime: default close module cache (#1604) (ba378a6)
- runtime: enable cors in runtime; disable cors in gateway ingress (#1603) (06cafd4)
- runtime: fix compile error (#1563) (3878bc0)
- runtime: fix db stream initialize (#1592) (40e25f1)
- runtime: fix runtime cors options (#1607) (366a6a4)
- runtime: fix update function not effective (#1597) (0c9daa3)
- runtime: support default function (#1602) (04905dc)
- server: add storage service conf for runtime, add cors conf for bucket ingress (fc73e6f)
- server: fix nest deps missing (#1564) (7781a3e)
- server: fix not reapply service when restart app (#1578) (bb9e8e2)
- server: fix runtime deployment labels (#1585) (93de793)
- server: fix user quota (#1534) (d3a2e65)
- server: fixed runtime manifest labels (#1583) (364c7a6)
- server: set deleting phase for runtime domain and website when deleting app (#1613) (27b0587)
- server: update logic of cronjob deletion (#1623) (fb7a45d)
- web: disable navigate cache for api endpoint (#1579) (f7b8775)
- web: fix bucket display name in edit mode (#1606) (d16bb36)
- web: fix create function default code (#1544) (0b903e8)
- web: fix delete button covered in dependency panel (#1546) (b065acd)
- web: fix files can't be accessed before refreshing & change file path (#1538) (86250d9)
- web: fix function list folder name display (#1561) (1f7d6af)
- web: fix params not update & change function list type (#1535) (5366201)
- web: fix sentry allowlist (#1587) (6c812bd)
- web: fix sign up navigate & storage display (#1580) (7dac760)
- web: remove storage.credential (#1594) (8e5f568)
Features
- cli: improve the cli interface (#1591) (fdbfc5c)
- cli: support database export and import (#1540) (8c68089)
- gateway: refactor gateway to support ingress (#1559) (155814b)
- runtime: add Access-Control-Max-Age to cors options (#1615) (c4b79fb)
- runtime: proxy cloud storage & website hosting request to minio (#1560) (5456de2)
- runtime: refactor function engine (#1590) (811066b)
- runtime: reuse context (#1539) (acafda5)
- server: add runtime affinity settings in region (#1548) (d3da138)
- server: add sealos manager labels to rumtime manifest(#1577) (f71ea31)
- server: add tls config for ingress gateway (#1569) (8751858)
- server: support github login (#1542) (14540c1)
- web: add client settings & change settings directory (#1536) (d22fd4e)
- web: add database indexes management (#1611) (f8c068a)
- web: add function list desc-name display & fix editor min-h (#1545) (2b252f2)
- web: optimize editor ctx type definition (#1558) (b3ecb45)
- web: support github login (#1543) (e8b8380)