如何在hasura graphql引擎上上传文件或图片
How to upload files or images on hasura graphql engine
示例:
- 将文件上传到服务器并将生成的路径保存到数据库,只有经过身份验证的用户才能上传文件
如何实现?
总而言之,我们有 3 种方式:
- 客户端上传到s3(或类似服务),获取文件url,然后向右insert/update突变table
- 自定义上传器 - 编写 application/server 上传文件并改变数据库并使用 nginx 路由将一些请求重定向到它
- 使用模式拼接的自定义解析器(example)
如果您要将文件上传到 AWS S3,有一种简单的方法,您无需启动另一台服务器来处理文件上传或为 hasura 操作创建处理程序。
基本上,当您将文件上传到 S3 时,最好从后端获得签名 url 并直接上传到 s3。顺便说一句,对于多种图像尺寸的托管,this approach 简单而轻松。
关键是如何让s3签名url上传。
在node.js,你可以做到
const AWS = require("aws-sdk");
const s3 = new AWS.S3({ apiVersion: "2006-03-01" });
const signedUrl = s3.getSignedUrl("putObject", {
Bucket: "my-bucket",
Key: "path/to/file.jpg",
Expires: 600,
});
console.log("signedUrl", signedUrl);
signedUrl 示例类似于 https://my-bucket.s3.amazonaws.com/path/to/file.jpg?AWSAccessKeyId=AKISE362FGWH263SG&Expires=1621134177&Signature=oa%2FeRF36DSfgYwFdC%2BRVrs3sAnGA%3D
。
通常,您会将上述代码放入 AWS Lambda 或 glitch 中托管的处理程序,并添加一些授权逻辑,甚至添加一行 table.
你可以看到最重要的部分是Signature=oa%2FeRF36DSfgYwFdC%2BRVrs3sAnGA%3D
。我们怎样才能更容易获得签名?
深入研究 AWS JS SDK 后,我们可以发现签名已计算 here。
return util.crypto.lib.createHmac(fn, key).update(string).digest(digest);
fn = 'sha1'
string = 'PUT\n\n\n1621135558\b/my-bucket/path/to/file.jpg'
digest = 'base64'
就是sha1某种格式的字符串。这意味着我们可以只使用 hasura 计算字段和 Postgres 加密函数来获得相同的结果。
因此,如果您有 table 个“文件”
CREATE TABLE files (
id SERIAL,
created_at timestamps,
filename text,
user_id integer
);
你可以创建一个SQL函数
CREATE OR REPLACE FUNCTION public.file_signed_url(file_row files)
RETURNS text
LANGUAGE sql
STABLE
AS $function$
SELECT ENCODE( HMAC(
'PUT' ||E'\n'||E'\n'||E'\n'||
(cast(extract(epoch from file_row.created_at) as integer) + 600)
||E'\n'|| '/my-bucket/' || file_row.filename
, 'AWS_SECRET', 'SHA1'), 'BASE64')
$function$
最后,按照 this 将此计算字段公开给 Hasura。
通过这种方式,您可以不添加任何后端内容并在 Hasura 中处理所有权限。
示例:
- 将文件上传到服务器并将生成的路径保存到数据库,只有经过身份验证的用户才能上传文件
如何实现?
总而言之,我们有 3 种方式:
- 客户端上传到s3(或类似服务),获取文件url,然后向右insert/update突变table
- 自定义上传器 - 编写 application/server 上传文件并改变数据库并使用 nginx 路由将一些请求重定向到它
- 使用模式拼接的自定义解析器(example)
如果您要将文件上传到 AWS S3,有一种简单的方法,您无需启动另一台服务器来处理文件上传或为 hasura 操作创建处理程序。
基本上,当您将文件上传到 S3 时,最好从后端获得签名 url 并直接上传到 s3。顺便说一句,对于多种图像尺寸的托管,this approach 简单而轻松。
关键是如何让s3签名url上传。
在node.js,你可以做到
const AWS = require("aws-sdk");
const s3 = new AWS.S3({ apiVersion: "2006-03-01" });
const signedUrl = s3.getSignedUrl("putObject", {
Bucket: "my-bucket",
Key: "path/to/file.jpg",
Expires: 600,
});
console.log("signedUrl", signedUrl);
signedUrl 示例类似于 https://my-bucket.s3.amazonaws.com/path/to/file.jpg?AWSAccessKeyId=AKISE362FGWH263SG&Expires=1621134177&Signature=oa%2FeRF36DSfgYwFdC%2BRVrs3sAnGA%3D
。
通常,您会将上述代码放入 AWS Lambda 或 glitch 中托管的处理程序,并添加一些授权逻辑,甚至添加一行 table.
你可以看到最重要的部分是Signature=oa%2FeRF36DSfgYwFdC%2BRVrs3sAnGA%3D
。我们怎样才能更容易获得签名?
深入研究 AWS JS SDK 后,我们可以发现签名已计算 here。
return util.crypto.lib.createHmac(fn, key).update(string).digest(digest);
fn = 'sha1'
string = 'PUT\n\n\n1621135558\b/my-bucket/path/to/file.jpg'
digest = 'base64'
就是sha1某种格式的字符串。这意味着我们可以只使用 hasura 计算字段和 Postgres 加密函数来获得相同的结果。
因此,如果您有 table 个“文件”
CREATE TABLE files (
id SERIAL,
created_at timestamps,
filename text,
user_id integer
);
你可以创建一个SQL函数
CREATE OR REPLACE FUNCTION public.file_signed_url(file_row files)
RETURNS text
LANGUAGE sql
STABLE
AS $function$
SELECT ENCODE( HMAC(
'PUT' ||E'\n'||E'\n'||E'\n'||
(cast(extract(epoch from file_row.created_at) as integer) + 600)
||E'\n'|| '/my-bucket/' || file_row.filename
, 'AWS_SECRET', 'SHA1'), 'BASE64')
$function$
最后,按照 this 将此计算字段公开给 Hasura。
通过这种方式,您可以不添加任何后端内容并在 Hasura 中处理所有权限。