阿里云前端 OSS 直传

avatar
avatar
admin
1485
文章
4
评论
2020年9月29日11:05:34 评论 159 1973字阅读6分34秒

在我们日常开发中,经常会遇到用户上传图片、视频的需求。

这类需求的传统实现方案是用户上传的图片、视频需要先上传到 Web 服务器再中转到 OSS 服务器,这样做会有几个问题:

  1. 客户端并发上传,对服务器带宽和性能都是不小的压力;
  2. 文件中转,需要耗费更多的流量和时间;
  3. 无法做到上传进度展示(Web 服务器中转上传时间未知)。

但是如果直接在前端进行签名上传的话,就会有安全问题(泄露秘钥),因此就有了服务端签名,前端直传方案。

方案流程

阿里云前端 OSS 直传

服务端签名

这里使用 nodejs 作为示例。有官方的 SDK,省去我们对接阿里云 HTTP 接口造轮子的时间。

安装 SDK

我使用的 sdk 是 ali-oss:https://github.com/ali-sdk/ali-oss。

吐槽下,阿里 sdk 命名不统一,@alicloud/xxxali_sdk/xxx ...

执行 npm install 安装 sdk。

npm install ali-oss --save

构建 Post Policy,获取上传签名

这里可以参照下官方 SDK 的 demo:https://github.com/ali-sdk/ali-oss/blob/master/example/server/postObject.js

const config = {
  accessKeyId'',
  accessKeySecret'',
  // 上传 bucket endpoint
  endpoint: ''
  bucket: ''
}

// 从初始化 OSS
const client = new OSS(config)

// 构建 policy 对象
const date = new Date();
// 获取过期时间为1天,这里可以根据情况,自己设置过期时间
date.setDate(date.getDate() + 1)
const policy = {
  expiration: date.toISOString(), // 请求有效期
  conditions: [
    ['content-length-range'01048576000], // 设置上传文件的大小限制
    { bucket: client.options.bucket } // 限制可上传的bucket(可选)
  ]
}

// 获取上传签名
const formData = await client.calculatePostSignature(policy)

// 返回给前端
return {
  formData,
  url: config.endpoint
}

Post Policy 的详细介绍:https://help.aliyun.com/document_detail/31988.html

必须包含 expiration 和 conditions。

Expiration: 指定过期时间
Conditions:是一个列表,用来指定 Post 请求的表单域合法值。

Conditions 使用方式见下图:

阿里云前端 OSS 直传

前端使用签名直传

这里以支付宝小程序为例,其他平台类似。

// 假设服务端获取上传签名接口返回值存储到 apiRet 变量

/**
 * apiRet: {
 *  url: 'oss上传url',
 *  formData: {
 *    // ... 上传所需参数、签名
 *  }
 * }
 */

alipay.uploadFile({
  url: apiRet.url,
  formData: {
    // 存储到 bucket 的路径
    key: "",
    // 设置成功返回的状态值 200
    success_action_status: 200,
    // 解构 接口返回 formData
    ...apiRet.formData,
  },
  // 文件名一定要是 file
  name: "file",
  // 支付宝小程序需要指定
  fileType: "image",
  filePath"",
});

需要注意的安全问题

有一个安全问题需要注意,如果黑客获取签名后,可以直接伪造请求,覆盖之前用户上传的图片,假如用户之前上传的是自己的付款码,可以直接修改为黑客的付款码。

解决方案

生成签名时,conditions 指定 key 前缀(可以使用基于时间戳的 uuid 或 user id),前端上传时,使用该前缀 key + 前端 key 上传。

那今天关于阿里云 OSS 前端直传的分享就到这啦~

 

匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: