小弟只写过前端,没写过后端,现在写个小项目需要后端的一些实现。有个逻辑不太清楚应该怎么实现。
文件上传使用 minio 做文件存储。当前端想上传文件时候,前端请求一个 api 给后端,后端生成一个预签名的 minio url ,前端拿到这个上传链接进行上传。
上传完成后,前端是否需要再调用一次接口,将上传完成这个动作通知后端。
虽然 minio 有 webhook 功能,支持上传完成后调用后端接口通知后端程序。但这样和前端是并行的。上传完成后需要将一些信息写入到数据库,比如数据库有一个 state 状态标志着是否上传完成,以及上传完成后的 minio 直链。
如果使用 webhook 这种,前端上传完成后会立即刷新页面,但此时后台还没有完成数据库更新操作,数据刷新会不及时。
但是如果使用再加一个 api 让前端调用,感觉有点复杂,一个上传逻辑需要 3 个接口请求。
所以最佳实践是什么样的?

肯定要通知啊。工作嫌麻烦,不如回家躺平

我现在就是在家躺平呢,没事干。写一下代码打发时间。

用 mq 解耦啊

具体流程如下:
1 、前端调用后端文件上传认证接口:CreateFile ,获取 s3 地址和临时认证信息。
2 、前端根据 CreateFile 接口获取的 s3 信息,使用 s3 sdk 上传文件。例如( aws.amazon.com/cn/developer/)
3 、前端调用后端文件上传完成通知接口:UpdateFile ,通知后端上传结果和文件名。
4 、前端调用后端 GetFile 获取文件下载地址。

前端通知你和不通知你的情况你都要处理。
万一前端上传完文件刚好流量用完了呢

我认为不需要通知,数据库里不存关于文件的任何信息。

搜一下阿里云 oss sts 上传

一般文件不是至少关联一个实体实例吗?文件传完前端不用让后端更新对应的实体字段?前面预签名是要临时权限,把业务逻辑分一部分写在那里面才叫麻烦...

如果是自己的玩具项目,就没必要通知了,后端把上传密钥和 pathname 返回给前端,并直接把这个 pathname 存到数据库中,直接当成前端已上传成功(万一部分极端情况前端上传失败,就自己走编辑流程,重新从头上传一次呗)

建议后端调用文件储存接口,并处理回调。这样前端只要把文件扔给后端并等待 URL 返回就好

用 cursor ,把你需求说出来就行了

这个方法确实方便。直接把桶的策略改成所有人都可以 read

Access permission for minio/bucket is download

哈哈哈

不通知会有一个问题,有些文件传了根本没用过,这些文件积压下来,时间长了有几百 G,根本就找不到

REPS

歪个楼,要怎么解决恶意用户调用上传接口上传了一堆文件不通知后端的;加个定时任务来检查 s3 里面有没有不该存在的文件吗

首先是权限问题,oss 有 sts ,就相当于临时身份
前端拿 sts 直接上传 oss ,分段上传后调用 complete 请求给后端

有个思路是
用于上传的临时 bucket 设置一个过期时间,比如 1 小时,并限制单个文件大小。
调用 update 上传成功后的文件,拷贝到真正要归档的 bucket 中。

桶读权限开放的话,小心有人恶意 list 然后下载数据或者刷流量...

我接手过的项目都是把文件上传+回调的所有逻辑统一交给后端处理,前端只调用 /upload 然后显示状态即可。对于公开的项目,你不能确保前端一定不会出错,如果 callback 执行中断或者恶意被执行,往小了说可能会影响数据完整性,如果这个 callback 涉及到敏感逻辑,可能出现安全问题。

不如把问题泛化一下,三方调用,客户端,后端,第三方,

  1. 客户端请求后端,后端调用第三方生成凭据后返回给客户端使用。
  2. 客户端拿着凭据调用第三方,完成后应当如何?

有两个通知途径,

  1. 客户端通知服务端调用结果
  2. 第三方回调通知服务端

第 1 种方式,实时性比较高,用户体验更好,但很容易因为客户端网络或者关闭页面,导致通知丢失。
第 2 种方式,实时性稍差,但可靠性很高,可以按照一定时间间隔多尝试几次通知。
第 3 种方式,属于 fallback 兜底,服务端周期性轮询未知状态的凭据,做相应处理。

第 2 种是必须的,实时性要求高,再加上第 1 种。

更常见的场景是微信支付宝的支付。

1.发起请求我要上传文件
1.1 验证前端的 token 文件长度 文件名称 等文件 文件归属用户 信息
1.2 服务器接收到 验证完成预生成一个文件
1.3 客户端开始上传服务器开始写入
1.4 客户端上传完成把预生成文件写入一个标记为完成状态
1.5 客户端拉取列表展示最新的文件列表

你说的这个在第一步就已经完成了.

看到你这个 早期的美团外卖就做过这种”蠢事“
就是大规模应用场景几乎不能用客户端通知
美团外卖当时的是: 付款跳回 app 本身才通知支付完成->后台->商家有新的订单.
现在美团估计是双端都会通知. 做了锁处理接着执行后续逻辑.

当然要,如果嫌麻烦,可以写一个 lambda ,由 S3 存储桶触发后端来更新数据库状态。

+1 ,上传文件难道不是应该后端来处理吗