OSS实现安全可靠的文件上传

644 阅读2分钟

结合 阿里云对象存储 OSSVan-UploaderAxios 实现文件上传,以下是实现的详细步骤:

1. 实现思路

  1. 后端生成 OSS 的 PolicySignature(为了安全性)。
  2. 前端使用 Van-Uploader 组件收集文件,并通过 Axios 将文件上传到 OSS。
  3. 在上传成功后,获取 OSS 文件的 URL,供后续使用。

2. 安装所需依赖

确保项目中安装了以下依赖:

npm install axios  ali-oss

3. 后端代码:生成 Policy 和 Signature

使用 Node.js 作为示例(也可以用其他语言实现):

const crypto = require('crypto');

// 阿里云 OSS 配置信息
const OSSConfig = {
  region: 'oss-cn-hangzhou', // 地域
  accessKeyId: '<YourAccessKeyId>',
  accessKeySecret: '<YourAccessKeySecret>',
  bucket: '<YourBucketName>',
};

// 生成 Policy 和 Signature
const generatePolicyAndSignature = () => {
  const policy = {
    expiration: new Date(Date.now() + 5 * 60 * 1000).toISOString(), // 5分钟过期
    conditions: [
      ['content-length-range', 0, 5 * 1024 * 1024], // 文件大小限制 5MB
      ['starts-with', '$key', 'uploads/'], // 文件路径限制
    ],
  };

  const policyBase64 = Buffer.from(JSON.stringify(policy)).toString('base64');
  const signature = crypto
    .createHmac('sha1', OSSConfig.accessKeySecret)
    .update(policyBase64)
    .digest('base64');

  return {
    policy: policyBase64,
    signature,
    accessKeyId: OSSConfig.accessKeyId,
    bucket: OSSConfig.bucket,
    region: OSSConfig.region,
  };
};

// 示例:返回签名信息给前端
app.get('/api/oss/signature', (req, res) => {
  const data = generatePolicyAndSignature();
  res.json(data);
});

4. 前端代码:Van-Uploader 配置和上传

Van-Uploader 的基本配置

引入 Vant 的 Uploader 组件:

<template>
  <van-uploader
    :after-read="handleAfterRead"
    multiple
    max-size="5242880" <!-- 限制文件大小 -->
    max-count="5"
  />
</template>

<script>
import axios from 'axios';

export default {
  methods: {
    async handleAfterRead(file) {
      // 上传文件
      await this.uploadToOSS(file.file);
    },
    async uploadToOSS(file) {
      try {
        // 获取签名信息
        const { data } = await axios.get('/api/oss/signature');

        // 构造 FormData
        const formData = new FormData();
        formData.append('key', `uploads/${file.name}`);
        formData.append('policy', data.policy);
        formData.append('OSSAccessKeyId', data.accessKeyId);
        formData.append('signature', data.signature);
        formData.append('file', file);

        // 上传文件到 OSS
        const ossUrl = `https://${data.bucket}.${data.region}.aliyuncs.com/`;
        const response = await axios.post(ossUrl, formData);

        if (response.status === 204) {
          console.log('文件上传成功:', ossUrl + `uploads/${file.name}`);
        } else {
          console.error('文件上传失败:', response);
        }
      } catch (err) {
        console.error('上传出错:', err);
      }
    },
  },
};
</script>

5. 整体流程解读

  1. 前端获取签名
    • 前端调用 /api/oss/signature 获取上传所需的 policysignature
    • 签名由后端生成,前端无法篡改,保证安全性。
  1. Van-Uploader 处理文件
    • after-read 回调接收文件,构造 FormData
  1. 通过 Axios 上传文件
    • 将文件和签名信息通过 POST 请求上传到 OSS 的存储桶。
  1. 上传完成
    • 如果 OSS 返回 204 状态码,则上传成功。
    • 前端可以将生成的文件 URL 存储到数据库或用于展示。

6. 注意事项

  1. 安全性
    • 永远不要将 AccessKeySecret 直接暴露到前端。
    • 使用后端生成签名的方式,确保安全。
  1. 跨域问题
    • OSS 的存储桶设置为 公共读,以便跨域访问。
    • 如果使用自定义域名,请配置正确的 CORS 规则。
  1. 文件路径管理
    • 使用 key 指定上传路径,例如 uploads/2025/01/02/file.jpg,便于后续管理。
  1. 文件大小限制
    • 在 Policy 中设置 content-length-range,同时前端限制上传文件大小。

通过这种方式,Van-Uploader 的直观界面和 OSS 的高效存储结合在一起,能快速实现安全可靠的文件上传。