如何在 hasura graphql 引擎上上传文件或图像

Posted

技术标签:

【中文标题】如何在 hasura graphql 引擎上上传文件或图像【英文标题】:How to upload files or images on hasura graphql engine 【发布时间】:2019-03-14 13:16:55 【问题描述】:

例子:

将文件上传到服务器并将生成的路径保存到数据库,只有经过身份验证的用户才能上传文件

如何实现?

【问题讨论】:

【参考方案1】:

总结一下,我们有 3 种方式:

客户端上传到 s3(或类似服务),获取文件 url,然后对正确的表进行插入/更新突变 自定义上传器 - 编写上传文件和改变数据库的应用程序/服务器,并使用 nginx 路由将一些请求重定向到它 使用模式拼接的自定义解析器 (example)

【讨论】:

【参考方案2】:

如果您将文件上传到 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 或故障中托管的处理程序中,并添加一些授权逻辑,甚至在表中添加一行。

可以看到最重要的部分是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 加密函数来获得相同的结果。

所以如果你有一个表“文件”

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 中处理权限。

【讨论】:

虽然这看起来很吸引人,但此签名是 v2 签名,自 2018 年以来已被弃用。当前的 v4 签名在 SQL 中计算难度显着提高。

以上是关于如何在 hasura graphql 引擎上上传文件或图像的主要内容,如果未能解决你的问题,请参考以下文章

使用 Hasura graphql 模式时如何自定义 graphql-code-generator 生成的字段的类型

如何从 iOS 中的 hasura graphql 查询中获取错误响应

比较 GraphQL Hasura 中的两个字段

如何在 Apollo 客户端中传递地理查询变量(使用 React Native / Hasura GraphQL)

hasura graphql 模式拼接demo

hasura graphql-engine ha 以及自动缩放的一些参考资料