ui设计比较成功的网站页面,企业网站开发公司排名,网页制作员薪资,衡水建站公司敏博科技专业致力于应急管理行业#xff0c;提供以物联网技术和感知预警算法模型为核心的先进产品和解决方案。应急管理行业的业务非常繁多和复杂#xff0c;很多时候都需要在短时间内交付出稳定高效的业务系统。如下两张图某市的安全生产监测预警系统
MemFire Cloud应用开…敏博科技专业致力于应急管理行业提供以物联网技术和感知预警算法模型为核心的先进产品和解决方案。应急管理行业的业务非常繁多和复杂很多时候都需要在短时间内交付出稳定高效的业务系统。如下两张图某市的安全生产监测预警系统
MemFire Cloud应用开发服务采用开源的Supabase兼容国内开发生态内置通用服务简单易学加速小程序/移动应用/WEB网站的开发降低开发/运维成本。
Supabase在简化开发过程提供开发人员所需的核心后端服务使开发人员能够更轻松地构建和管理应用程序的后端部分同时让前端人员自己了解业务与数据库表结构设计前端数据渲染与交互通讯减少沟通成本从而加速应用程序的开发周期。
MemFire Cloud引用了supabase的整套工程并且接入到自己的平台里保证数据不在国外的问题了方便追溯。而且在国外的话访问速率也是一个问题有的网络情况可能访问不到supabase的服务这也是为什么我没有选择直接使用supabase的重要原因之一。国内的项目当然更适合国内自己的生态啦
那么下面我将分享使用MemFire Cloud开发这两个应用的部分案例和所遇到的问题。
使用MemFire Cloud开发可视化项目遇到的一些问题 身份认证服务
登录方式
MemFire Cloud提供了极其便利和丰富的身份认证服务。你可以通过几种方式来验证你的用户
微信小程序电子邮件和密码Magic links一键登录其他社交媒体登录认证服务商手机号登录
但是往往用户信息功能通常都是在自己的服务器里存储这样有利于更多的可定制化一些其他的功能所以我们需要将自己的用户表和MemFire Cloud的用户表进行关联。
关联用户
你可以在 表编辑器 的 Schema auth 里面找到 users 表这个表就是MemFire Cloud身份认证所需的用户信息。
那么问题来了我们自己的业务系统里的用户只能通过账号和密码进行登录但是MemFire Cloud的身份认证服务没有账号的方法所以我们将使用邮箱账号的方式进行注册和登录只需要在自己的业务系统里注册和登录的时候后面添加一个邮箱后缀即可。
下面是邮箱注册的方法
// 邮箱注册
let { data, error } await supabase.auth.signUp({email: blacknimblex.com,password: xxxxxxxx
})下面是邮箱登录的方法 // 邮箱登录let { data, error } await supabase.auth.signInWithPassword({email: blacknimblex.com,password: xxxxxxxx
})这样就完成了身份认证的功能 权限RLS
应用场景
假如所有的用户只能获取该用户所属部门的数据不能获取非本部门的数据。
以上场景可能大部分人第一想法是将这个数据通过部门的ID进行关联查询但是这种做法会导致重复的代码查询逻辑和更多的代码维护量所以选择使用RLS是最佳选择。
什么是RLS
全称Row level security行级安全允许系统管理员为数据库表创建访问策略policy以约束数据的可见性。当为一个表创建了policy后相当于为该表增加了一个高优先级的过滤器。当用户访问该表时如果policy生效则会根据policy中定义的过滤条件来决定用户可操作的数据集合。
开启RLS
界面上可以比较方便的对每个表开启和关闭RLS但是不方便代码维护因此这里采用SQL语句的方式对需要开启RLS的表进行管理。基本的语法
alter table xxx enable row level security;权限模型
目前项目中的数据权限统一采用一种模型用户可以查看本部门以及子部门的所有数据。因此RLS规则相对简单。
插件依赖
为了提高RLS的性能这里引入一个Postgres插件supabase-custom-claims该插件可以将一些用户属性信息写入到auth.users表中并且在用户登录时写入到会话上下文的变量中方便直接使用。这里我们通过该插件将用户的部门id以及部门行政区域编码写入到用户session缓存中。
用户同步
为了确保用户不论通过supabase还是通过后台管理系统里的注册、添加、修改密码、修改部门等功能两边都保持数据同步需要为此创建触发器进行用户的同步。这里需要通过set_claims修改用户的属性信息将dept_id和code写入auth.users表。代码参见。
初始用户搬迁
将已经存在的用户从sys_user表同步到supabase代码参见。
RLS规则
为了满足权限模型的需求RLS规则基本上会经常使用到如下两个判断
可以看当前部门的数据
-- 假设表中有dept_id字段则RLS规则写法如下
get_my_claim(dept_id) to_jsonb(dept_id::text)
-- 如果表中只有行政区域编码则RLS规则写法如下 (可能有的表不叫qxbm比如xzqhdm请根据实际情况修改
get_my_claim(dept_code) to_jsonb(qxbm::text) 可以查看子部门的数据
-- 假设表中dept_id字段则RLS规则写法如下
dept_id in (select dept_id from sys_dept d where get_my_claim(dept_id::text) # {} any (string_to_array(ancestors, ,))
)
-- 表中只有行政区划编码的情况
qxbm in (select code from sys_dept d where get_my_claim(dept_id::text) # {} any (string_to_array(ancestors, ,))
)视图处理
视图可以简化开发但是存在一个需要解决的问题Postgres不支持为视图创建RLS并且默认情况下视图对应的表如果配置了RLS规则查询视图时规则是不生效的导致查询视图会把不应该看到的数据也返回了。要解决该问题必须为视图开启security invoker。
PostgreSQL 15之前的版本 如何在 PostgreSQL 中的视图添加行级安全PostgreSQL 15 PostgreSQL中的视图权限和行级安全性
基本用法
-- 创建视图的时候开启
create view new_type_view with (security_invoker true ) as select * from source_data;-- 对已有视图开启
ALTER VIEW xxxx SET (security_invoker on);RLS规则
从项目角度不需要为所有表创建RLS通常只需要为主表创建RLS。主表的意思是约束数据查询范围的表比如部门表、企业表等。
另外一个判断是否需要创建RLS的依据是否有业务场景根据用户输入直接查询该表。
比如只要约束了部门表用户就无法从sys_dept表中查询不属于自己权限范围内的部门ID也就无法通过部门ID去查询更多数据。
sys_dept 表
alter table dept enable row level security;-- 允许用户查询所在部门的信息
CREATE POLICY 可以查询当前部门信息 ON public.sys_dept
AS PERMISSIVE FOR SELECT TO public
USING (get_my_claim(dept_id) to_jsonb(dept_id::text))-- 允许用户查询子部门的信息
CREATE POLICY 可以查下子部门信息 ON public.sys_dept
AS PERMISSIVE FOR SELECT TO public
USING ( get_my_claim(dept_id::text) # {} any (string_to_array(ancestors, ,)) )sys_enterprise 表
alter table sys_enterprise enable row level security;-- 允许用户查询所在部门的行政区划的数据
CREATE POLICY 可以查看当前行政区划的数据 ON public.sys_enterprise
AS PERMISSIVE FOR SELECT TO public
USING (get_my_claim(dept_code) to_jsonb(xzqhdm::text))-- 允许用户查询子部门的行政区划的数据
CREATE POLICY 可以查看下级行政区划的数据 ON public.sys_enterprise
AS PERMISSIVE FOR SELECT TO public
USING (xzqhdm in (select code from sys_dept d where get_my_claim(dept_id::text) # {} any (string_to_array(ancestors, ,)) ))删除Policy
删除很简单可以通过界面删除也可以使用SQL删除
drop policy xxx on xxx;多种类多维度的数据统计
在数据可视化大屏当中难免会遇到一个情况需要统计多种类、多维度的数据来填充单个卡片例如下图
在后端开发人员的设计接口开发思路里这段SQL语句肯定要用到Group By语法并将这几种类型的统计汇总后统一返回给前端。
但是在Supabase的API里计数查询不支持类似于Group By方式查询只能针对单个条件进行计数代码如下
const { count, error } await supabase.from(countries).select(*, { count: exact, head: true })那么在前端是否就只能根据上面卡片的需求调用8次api呢
当然不是因为这样会造成重复的过多代码量和线程阻塞后期维护复杂
如何解决
所以针对这样的问题我总结了以下几种方法
使用数据库函数让后端人员开发数据库函数前端使用SupabaseApi调用 const { data,error } await supabase.rpc(func_get_risk_conut) 函数获取统计数据。可以考虑使用查出表内所有数据在前端进行计算。如果涉及多表可以建立视图表。该方案仅适用于只涉及到单表且数据量不大的场景让后端人员针对该业务比如不同维度和种类的风险功能进行建立视图然后前端调用视图查询。
小结
通过实践发现方案2和方案3均有不同程度的性能问题因此方案1更佳。
总结
MemFire Cloud 功能强大使用它开发项目的效率极高项目开发的周期能够被缩短同时还能减少投入的后端开发人员并且换了一种开发模式。可能正常的开发模式是后端设计流程和开发接口前端开发页面和对接接口但现在只需要前端开发页面、设计流程和获取数据即可。
再谈谈优缺点
MemFire Cloud 支持多种常见的身份认证方式包括email、各平台登录为开发者提供了灵活的选择适应不同用户的偏好。但是存在着一些 局限性 尽管提供了多种认证方式但再一些特殊需求下开发者可能需要更多的自定义选项这方面的灵活性可能不如一些专业身份认证服务。RLS允许开发者以行级为单位和控制用户对数据库中数据的访问权限实现了精细的访问控制和数据保密性并且RLS是再数据库层面实现的这意味着访问控制直接集成到数据库引擎中提供了高效和可靠的数据保护。但是对于复杂的数据结构和多层级的访问控制配置可能会变得复杂需要谨慎的规划和设计以确保正确的分配权限。Supabase的API在提供便捷的同时开箱即用无需复杂的配置就可以开始使用创建表后可以直接通过前端调用api的形式进行数据库的增删改查。但还是很难满足比较苛刻和复杂的查询需求。
通过这个项目了解到MemFire Cloud和学习了Supabase的功能其中它的一些特性比如Postgres数据库服务、认证服务、自动生成API、文件存储等功能是这次项目的主要内容还有更多的功能与服务例如REST ApiRealtime、静态托管、云函数等功能。
考虑到Supabase是一个不断发展的开源项目未来也会不断增强其现有的功能和开辟新的功能例如数据库查询优化、安全性增强、第三方集成、更多的数据库语法API我相信 **MemFire Cloud**在未来会发展成一个更加成熟应用业务面更广使用性更强的工具。