javascript - BigQuery 与“签名网址”的相似性
问题描述
我在 BigQuery 中有以下用例:
- 不受信任的用户将查询 BigQuery 表。假设查询是
SELECT * FROM [bigquery.table123]
. - 该查询将返回大量数据,例如 200MB,然后将显示在用户的浏览器中。
我们的目标是提供最有效的方式将 200MB 数据获取到用户的浏览器中(最糟糕的方式似乎是两次而不是一次——从 BQ 到我们的服务器,然后(压缩)到客户端)。我认为解决方案可能是让最终(不受信任的)用户获得类似“签名 URL”的东西,以便直接从他们的浏览器执行查询到 BigQuery。然后流程将是这样的:
- 用户向我们的后端发出查询。
- 身份验证完成,生成一个签名的 url 并传回 javascript。
- 然后客户端发送签名的 url,数据直接加载到浏览器中。
- 只能执行已授权的确切查询,而不能执行其他查询(例如,如果客户端从 javascript 复制了任何令牌)
我永远不会希望最终用户知道他们正在查询的 ProjectId 或表名称。
在 BigQuery 中可以做这样的事情吗?以下是Cloud Storage中类似需求的示例。以下是在浏览器中执行此操作的经过身份验证/受信任的用户的示例:https ://github.com/googleapis/nodejs-bigquery/blob/master/samples/browseRows.js或 . https://stackoverflow.com/a/11509425/651174,但是有没有办法在浏览器中为不受信任的用户执行此操作?
解决方案
下面是一个涉及两个级别的授权视图的选项。这不仅可以屏蔽最终用户的底层数据,还可以隐藏正在使用的确切数据
假设数据在 DatasetA 中。下面的步骤解释了逻辑
- 在 DatasetB 中创建 InternalView - 这将针对来自 DatasetA 的真实数据。
- 将 InternalView 设为 DatasetA 的授权视图
- 在 DatasetC 中创建 PublicView - 这个将针对 InternalView
- 将 PublicView 设为 DatasetB 的授权视图
- 授予用户对 DatasetC 的读取权限
用户可以运行 PublicView,它实际上是针对 readl 数据运行 PrivateView。
同时,用户将无法看到 PrivateView 的定义,因此永远不会知道ProjectId or Table Name(s) that they are querying
,等等。
注意:这不能解决how we'd prevent users from being able to issue queries that we haven't pre-authorized?
您的部分问题,但我会按照您的要求添加我的答案
同时 - 至少在理论上 - 您可以将一些逻辑嵌入到您的 PrivateView 中,这将查询一些内部元表,其中包含哪些用户以及何时允许获得结果的信息。假设这样的元表将由您的后端根据身份验证/令牌或您想到的任何其他内容进行管理
以下是该方法的简化和简要概述
#standardSQL
WITH `projectA.datasetA.table` AS (
SELECT 'data1' col UNION ALL
SELECT 'data2' UNION ALL
SELECT 'data3'
), `projectA.datasetA.applicationPermissions` AS (
SELECT 'user1@gmail.com' user UNION ALL
SELECT 'user2@gmail.com'
), `projectA.datasetB.privateView` AS (
SELECT d.*
FROM `projectA.datasetA.table` d
CROSS JOIN `projectA.datasetA.applicationPermissions` p
WHERE LOWER(user) = LOWER(SESSION_USER())
), `projectA.datasetC.publicView` AS (
SELECT *
FROM `projectA.datasetB.privateView`
)
SELECT *
FROM `projectA.datasetC.publicView`
如果user1@gmail.com
或user2@gmail.com
将在查询下方运行
SELECT *
FROM `projectA.datasetC.publicView`
他们会得到低于结果
Row col
1 data1
2 data2
3 data3
而如果user3@gmail.com
将运行相同的查询 - 结果将是
Row col
Query returned zero records.
显然,您可以扩展您的元表(applicationPermissions),例如允许用户获得结果的时间范围(需要添加检查时间条件的相应行projectA.datasetB.privateView
)
推荐阅读
- sql - sql中数据类型decimal(1, 1)和numeric (1, 1)的区别
- java - 如何保存android活动的状态
- javascript - 在 JavaScript 中更改“this”的上下文
- hadoop - 无法访问使用 hive 创建的数据库并在 hue 上运行查询
- php - 重定向时用户会话数据重置 (CodeIgniter)
- sql - 在 2 个日期之间的日期加入 2 个表
- python - 如何在多线回归中对解释变量进行平方
- events - 未捕获的错误:返回的值无效,是否耗尽了 Gas?
- javascript - 使用 recompose 实用程序作为元素
- ios - 如何从 swift 代码打开 waze carpool 应用程序?