经典案例|使用Supabase解决可视化大屏项目的常见问题

敏博科技专业致力于应急管理行业,提供以物联网技术和感知预警算法模型为核心的先进产品和解决方案。应急管理行业的业务非常繁多和复杂,很多时候都需要在短时间内交付出稳定高效的业务系统。如下两张图某市的安全生产监测预警系统
在这里插入图片描述
在这里插入图片描述

MemFire Cloud应用开发服务,采用开源的Supabase,兼容国内开发生态,内置通用服务,简单易学,加速小程序/移动应用/WEB网站的开发,降低开发/运维成本。

Supabase在简化开发过程,提供开发人员所需的核心后端服务,使开发人员能够更轻松地构建和管理应用程序的后端部分,同时让前端人员自己了解业务与数据库表结构设计前端数据渲染与交互通讯减少沟通成本,从而加速应用程序的开发周期。

MemFire Cloud引用了supabase的整套工程并且接入到自己的平台里,保证数据不在国外的问题了,方便追溯。而且在国外的话访问速率也是一个问题,有的网络情况可能访问不到supabase的服务,这也是为什么我没有选择直接使用supabase的重要原因之一。国内的项目当然更适合国内自己的生态啦!

那么下面我将分享使用MemFire Cloud开发这两个应用的部分案例和所遇到的问题。

使用MemFire Cloud开发可视化项目遇到的一些问题

  1. 身份认证服务

登录方式

MemFire Cloud提供了极其便利和丰富的身份认证服务。你可以通过几种方式来验证你的用户:

  • 微信小程序
  • 电子邮件和密码
  • Magic links(一键登录)
  • 其他社交媒体登录认证服务商
  • 手机号登录

但是往往用户信息功能通常都是在自己的服务器里存储,这样有利于更多的可定制化一些其他的功能,所以我们需要将自己的用户表和MemFire Cloud的用户表进行关联。

关联用户

你可以在 表编辑器Schema auth 里面找到 users 表,这个表就是MemFire Cloud身份认证所需的用户信息。

那么问题来了,我们自己的业务系统里的用户只能通过账号和密码进行登录,但是MemFire Cloud的身份认证服务没有账号的方法,所以我们将使用邮箱账号的方式进行注册和登录,只需要在自己的业务系统里注册和登录的时候后面添加一个邮箱后缀即可。

下面是邮箱注册的方法

//    邮箱注册
let { data, error } = await supabase.auth.signUp({
  email: 'black@nimblex.com',
  password: 'xxxxxxxx'
})

下面是邮箱登录的方法

 //    邮箱登录
 let { data, error } = await supabase.auth.signInWithPassword({
  email: 'black@nimblex.com',
  password: 'xxxxxxxx'
})

这样就完成了身份认证的功能

  1. 权限(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;
  1. 多种类多维度的数据统计

在数据可视化大屏当中难免会遇到一个情况:需要统计多种类、多维度的数据来填充单个卡片,例如下图
在这里插入图片描述

在后端开发人员的设计接口开发思路里,这段SQL语句肯定要用到Group By语法,并将这几种类型的统计汇总后统一返回给前端。

但是在Supabase的API里计数查询不支持类似于Group By方式查询,只能针对单个条件进行计数,代码如下:

const { count, error } = await supabase
  .from('countries')
  .select('*', { count: 'exact', head: true })

那么在前端是否就只能根据上面卡片的需求,调用8次api呢?

当然不是!因为这样会造成重复的过多代码量和线程阻塞,后期维护复杂!

如何解决

所以针对这样的问题我总结了以下几种方法:

  1. 使用数据库函数,让后端人员开发数据库函数,前端使用SupabaseApi调用 const { data,error } = await supabase.rpc('func_get_risk_conut') 函数获取统计数据。
  2. 可以考虑使用查出表内所有数据,在前端进行计算。如果涉及多表可以建立视图表。(该方案仅适用于只涉及到单表,且数据量不大的场景)
  3. 让后端人员针对该业务(比如不同维度和种类的风险)功能进行建立视图,然后前端调用视图查询。
小结

通过实践发现方案2和方案3均有不同程度的性能问题,因此方案1更佳。

总结

MemFire Cloud 功能强大,使用它开发项目的效率极高,项目开发的周期能够被缩短,同时还能减少投入的后端开发人员,并且换了一种开发模式。可能正常的开发模式是,后端设计流程和开发接口,前端开发页面和对接接口,但现在只需要前端开发页面、设计流程和获取数据即可。

再谈谈优缺点:

  • MemFire Cloud 支持多种常见的身份认证方式,包括email、各平台登录,为开发者提供了灵活的选择,适应不同用户的偏好。但是存在着一些 局限性 ,尽管提供了多种认证方式,但再一些特殊需求下,开发者可能需要更多的自定义选项,这方面的灵活性可能不如一些专业身份认证服务。
  • RLS允许开发者以行级为单位和控制用户对数据库中数据的访问权限,实现了精细的访问控制和数据保密性,并且RLS是再数据库层面实现的,这意味着访问控制直接集成到数据库引擎中,提供了高效和可靠的数据保护。但是对于复杂的数据结构和多层级的访问控制,配置可能会变得复杂,需要谨慎的规划和设计,以确保正确的分配权限。
  • Supabase的API在提供便捷的同时,开箱即用无需复杂的配置就可以开始使用,创建表后可以直接通过前端调用api的形式进行数据库的增删改查。但还是很难满足比较苛刻和复杂的查询需求。

通过这个项目了解到MemFire Cloud和学习了Supabase的功能,其中它的一些特性比如Postgres数据库服务、认证服务、自动生成API、文件存储等功能是这次项目的主要内容,还有更多的功能与服务例如REST ApiRealtime、静态托管、云函数等功能。

考虑到Supabase是一个不断发展的开源项目,未来也会不断增强其现有的功能和开辟新的功能,例如数据库查询优化、安全性增强、第三方集成、更多的数据库语法API,我相信 **MemFire Cloud**在未来会发展成一个更加成熟,应用业务面更广,使用性更强的工具。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/568671.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WordPress自动采集发布AutoPostPro汉化版插件

WP-AutoPostPro 是一款极为出色的WordPress自动采集发布插件,其显著优势在于能够从任何网站抓取内容并自动将其发布到你的WordPress网站上。它实现了对任何网页内容的自动采集和发布,整个采集过程完全自动化,无需手动操作。 项 目 地 址 &…

BM25检索算法 python

1.简介 BM25(Best Matching 25)是一种经典的信息检索算法,是基于 TF-IDF算法的改进版本,旨在解决、TF-IDF算法的一些不足之处。其被广泛应用于信息检索领域的排名函数,用于估计文档D与用户查询Q之间的相关性。它是一种…

【结构型模型】享元模式

一、享元模式概述 享元模式定义:又叫蝇量模式,运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细…

JVM--Java对象到底存在哪?

Java对象存放在堆中,但堆又分为新生代和老年代,新生代又细分为 Eden、From Survivor、To Survivor。那我们创建的对象到底在哪里? 堆分为新生代和老年代,新生代用于存放使用后就要被回收的对象(朝生夕死)&a…

vue项目使用百度地图

打开百度地图开放平台 百度地图开放平台 | 百度地图API SDK | 地图开发 在控制台新建应用 复制访问应用的ak 可修改地图样式 使用部分 <!-- 引入地图 --><div class"main-aside"><div id"b-map-container"></div></div> …

【数据结构】三、栈和队列:2.顺序栈共享栈(顺序栈的初始化,判空,进栈,出栈,读取栈顶,顺序栈实例)

文章目录 1.顺序栈1.1初始化1.2判空1.3进栈1.4出栈1.5读取栈顶1.6销毁栈❗1.7顺序栈c实例 2.共享栈2.1初始化2.2判满 1.顺序栈 用顺序存储实现的栈 顺序栈的缺点&#xff1a;栈的大小不可变。 #define MaxSize 10 //定义栈中元素的最大个数 typedef struct{ElemType data[…

图像哈希:全局+局部提取特征

文章信息 作者&#xff1a;梁小平&#xff0c;唐振军期刊&#xff1a;ACM Trans. Multimedia Comput. Commun. Appl&#xff08;三区&#xff09;题目&#xff1a;Robust Hashing via Global and Local Invariant Features for Image Copy Detection 目的、实验步骤及结论 目…

CPPTest实例分析(C++ Test)

1 概述 CppTest是一个可移植、功能强大但简单的单元测试框架&#xff0c;用于处理C中的自动化测试。重点在于可用性和可扩展性。支持多种输出格式&#xff0c;并且可以轻松添加新的输出格式。 CppTest下载地址&#xff1a;下载地址1  下载地址2 下面结合实例分析下CppTest如…

进程概念(进程第1篇)【Linux复习篇】

目录 1、冯诺依曼体系结构怎么画&#xff1f;中央处理器是什么&#xff1f;存储器是什么&#xff1f;每个部分有什么作用&#xff1f; 2、什么是操作系统&#xff1f; 3、什么叫进程&#xff1f;操作系统如何管理进程的&#xff1f; 4、怎么查看进程&#xff1f; 5、C语言…

springcloud Ribbon的详解

1、Ribbon是什么 Ribbon是Netflix发布的开源项目&#xff0c;Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的框架。 2、Ribbon能干什么 LB负载均衡(Load Balance)是什么&#xff1f;简单的说就是将用户的请求平摊的分配到多个服务上&#xff0c;从而达…

AI视频改字个性化祝福豪车装X系统uniapp前端开源源码下载

装X系统源码简介 创意无限&#xff01;AI视频改字祝福&#xff0c;豪车装X系统源码开源&#xff0c;打造个性化祝福视频不再难&#xff01; 想要为你的朋友或家人送上一份特别的祝福&#xff0c;让他们感受到你的真诚与关怀吗&#xff1f;现在&#xff0c; 通过开源的AI视频…

从0到1—POC编写基础篇(二)

接着上一篇 POC常用基础模块 urllib 模块 Python urllib 库用于操作网页 URL&#xff0c;并对网页的内容进行抓取处理。 urllib 包 包含以下几个模块&#xff1a; ●urllib.request - 打开和读取 URL。 ●urllib.error - 包含 urllib.request 抛出的异常。 ●urllib.parse - …

新技术前沿-2024-大型语言模型LLM的本地化部署

参考快速入门LLM 参考究竟什么是神经网络 1 深度学习 1.1 神经网络和深度学习 神经网络是一种模拟人脑神经元工作方式的机器学习算法,也是深度学习算法的基本构成块。神经网络由多个相互连接的节点(也称为神经元或人工神经元)组成,这些节点被组织成层次结构。通过训练,…

【网络安全】在网络中如何对报文和发送实体进行鉴别?

目录 1、报文鉴别 &#xff08;1&#xff09;使用数字签名进行鉴别 &#xff08;2&#xff09;密码散列函数 &#xff08;3&#xff09;报文鉴别码 2、实体鉴别 鉴别(authentication) 是网络安全中一个很重要的问题。 一是要鉴别发信者&#xff0c;即验证通信的对方的确是…

小扎宣布开放 Meta Horizo​​n OS

日前&#xff0c;Meta以“混合现实的新时代”为题的博文宣布向第三方制造商开放Meta Horizon OS&#xff0c;包括华硕、联想和微软Xbox等等&#xff1a; Meta正在朝着为元宇宙建立一个更开放的计算平台的愿景迈出下一步。Meta正在向第三方硬件制造商开放赋能Meta Quest设备的操…

使用 IPAM 解决方案简化分布式网络管理

随着组织在数字领域的全球扩张&#xff0c;分布式网络是不可避免的&#xff0c;这意味着&#xff0c;随着 IT 基础设施的发展&#xff0c;组织需要适应&#xff0c;这包括在不断增长的系统需求、应用程序堆栈、各种协议和安全防御中监控、现代化和简化流程和资源。在有效管理现…

AJAX——案例

1.商品分类 需求&#xff1a;尽可能同时展示所有商品分类到页面上 步骤&#xff1a; 获取所有的一级分类数据遍历id&#xff0c;创建获取二级分类请求合并所有二级分类Promise对象等待同时成功后&#xff0c;渲染页面 index.html代码 <!DOCTYPE html> <html lang&qu…

Pycharm代码规范与代码格式化插件安装

给大家分享两个PyCharm编辑器的插件&#xff0c;分别是pylint与autopep8&#xff0c;主要用来提高我们在使用python进行自动化测试编写以及性能测试脚本编写过程中的代码质量、可读性与美观性。 pylint&#xff1a; ● 代码检查工具&#xff1a;它可以帮助检查代码中的错误、…

pnpm 安装后 node_modules 是什么结构?为什么 webpack 不识别 pnpm 安装的包?

本篇研究&#xff1a;使用 pnpm 安装依赖时&#xff0c;node_modules 下是什么结构 回顾 npm3 之前&#xff1a;依赖树 缺点&#xff1a; frequently packages were creating too deep dependency trees, which caused long directory paths issue on Windowspackages were c…

明日方舟游戏助手:一键完成日常任务 | 开源日报 No.233

MaaAssistantArknights/MaaAssistantArknights Stars: 11.6k License: AGPL-3.0 MaaAssistantArknights 是一款《明日方舟》游戏的小助手&#xff0c;基于图像识别技术&#xff0c;支持一键完成全部日常任务。 刷理智、掉落识别及上传企鹅物流智能基建换班、自动计算干员效率…