问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

基于阿里云OSS的V4预签名实现文件上传和下载加密(Go)

创作时间:
作者:
@小白创作中心

基于阿里云OSS的V4预签名实现文件上传和下载加密(Go)

引用
CSDN
1.
https://blog.csdn.net/Tcicxo/article/details/143985133

本文将介绍如何基于阿里云OSS实现V4预签名的文件上传和下载功能。通过具体的代码实现,展示如何在Go语言环境中使用阿里云OSS进行文件存储和管理。

一、准备工作

开通阿里云 OSS 服务

首先需要在阿里云官网注册账号,并在控制台开通 OSS 服务,此处不赘述。

创建一个私有的 OSS bucket(存储空间)用于存放文件

  • 记录下 bucket 名称、所在区域(如 oss-cn-beijing )以及访问密钥(AccessKey ID 和 AccessKey Secret),这些信息将在后续代码用到。
  • 给你的bucket添加允许HTTPS方式访问的权限:

安装必要的 Go 库

导入aliyun - oss - go - sdk库来与阿里云 OSS 进行交互。可以通过以下命令在项目目录下安装:

go get github.com/aliyun/oss-go-sdk/oss

自定义配置

var (
    endpoint        = "oss-cn-你的oss桶所属地区.aliyuncs.com"
    accessKeyID     = "你的OSS访问ID"
    accessKeySecret = "你的OSS访问密钥"
    bucketName      = "你自定义的桶名称"
    CatalogPrefix   = "需要将文件上传到的相对地址(如/images)" //目录
)

二、上传

通过时间戳和随机字符生成随机的文件名称

func generateRandomString(length int) string {
    const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    b := make([]byte, length)
    for i := range b {
        b[i] = charset[rand.Intn(len(charset))]
    }
    return string(b)
}

获取文件扩展名

func getFileExtension(filename string) string {
    parts := strings.Split(filename, ".")
    if len(parts) > 1 {
        return parts[len(parts)-1]
    }
    return ""
}

基于OSS提供的V4签名算法实现文件上传

type postResponse struct {
    api.ReturnJson
}
func(ctx core.Context) {
    res := new(postResponse)
    // 单文件上传
    file, err := ctx.FormFile("image")
    if err != nil {
        //ctx.JSON(400, gin.H{"error": err.Error()})
        ctx.AbortWithError(core.Error(
            400,
            code.UploadCreateError,
            validation.Error(err)))
        return
    }
    client, err := oss.New(endpoint, accessKeyID, accessKeySecret)
    if err != nil {
        //ctx.JSON(500, gin.H{"error": err.Error()})
        ctx.AbortWithError(core.Error(
            500,
            http.StatusInternalServerError,
            validation.Error(err)))
        return
    }
    bucket, err := client.Bucket(bucketName)
    if err != nil {
        //ctx.JSON(500, gin.H{"error": err.Error()})
        ctx.AbortWithError(core.Error(
            500,
            http.StatusInternalServerError,
            validation.Error(err)))
        return
    }
    // 生成唯一的文件名
    now := time.Now()
    timeStamp := now.Format("20060102150405")
    randomStr := generateRandomString(8)
    imageName := timeStamp + "-" + randomStr + "." + getFileExtension(file.Filename)
    f, err := file.Open()
    if err != nil {
        //ctx.JSON(500, gin.H{"error": err.Error()})
        ctx.AbortWithError(core.Error(
            500,
            http.StatusInternalServerError,
            validation.Error(err)))
        return
    }
    //目录+图片名称
    err = bucket.PutObject(CatalogPrefix+imageName, f)
    if err != nil {
        //ctx.JSON(500, gin.H{"error": err.Error()})
        ctx.AbortWithError(core.Error(
            500,
            http.StatusInternalServerError,
            validation.Error(err)),
        )
        return
    }
}

三、下载

基于V4预签名获取单文件

func OssSign(path string) (signUrl string, err error) {
    cfg := oss.LoadDefaultConfig().
        WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
        WithRegion(region)
    client := oss.NewClient(cfg)
    getObjRequest := &oss.GetObjectRequest{
        Bucket: oss.Ptr(bucketNameDownload),
        Key:    oss.Ptr(path),
    }
    getObjResult, err := client.Presign(context.TODO(), getObjRequest)
    if err != nil {
        return "", err
    }
    //log.Printf("get object presign result:%#v\n", getObjResult)
    log.Printf("get object url:%#v\n", getObjResult.URL)
    return getObjResult.URL, nil
}

通过文件在OSS桶中的相对路径调用OssSign方法可获取带V4签名的URL下载链接。为保证数据安全,OSSV4预签名URL默认15分钟有效期,可修改。

获取用户头像的签名URL举例

avatarStr := "runner_default.png" //图片所在bucket桶的相对位置
avatarUrl, _ = util.OssSign(avatarStr)

返回示例,点击即可下载对应的文件(15分钟有效期):

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号