web项目文件存取思路3——阿里云oss+go| 青训营

100 阅读3分钟

本文介绍阿里云oss如何配置入go项目,并用go语言实现将文件存储至阿里云oss,并给出mysql数据库和oss如何结合的方案。

在阿里云oss控制台中进入Access Key入口,Access Key是访问阿里云 API 的密钥,在项目代码中需要调用到阿里云oss服务必须需要Access Key。只是一个简单web项目或学习使用时可以先不选择使用子用户Access Key(但一定要保存好小心泄露)。但阿里云账号AccessKey拥有所有API的访问权限,风险很高。官方强烈建议您创建并使用RAM用户进行API访问或日常运维。

image.png

创建AccessKey,并记录下AccessKey ID 和 AccessKey Secret后面将用到。

image.png

具体代码

导包和变量

安装阿里云oss依赖包

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

导入oss包。为了便于对bucket的全局管理,可以将bucket作为一个全局变量。

import (
  "github.com/aliyun/aliyun-oss-go-sdk/oss"
)
var bucket *oss.Bucket

初始化

func InitOss() {
    endpoint := ""
    accessKeyId := ""
    accessKeySecret := ""
    bucketName := ""
    client, err := oss.New(endpoint, accessKeyId, accessKeySecret)
    if err != nil {
       handleError(err)
    }
    bucket, err = client.Bucket(bucketName)
    if err != nil {
       handleError(err)
    }
}

填写先前记录下的bucket对应的endpoint。如华东1(杭州)为例,endpoint为oss-cn-hangzhou.aliyuncs.com。其它地域请按实际配置情况填写。

accessKeyId和accessKeySecret也为前面创建accessKey后记录下信息。

bucketName为bucket的唯一名称

调用oss.New方法创建OSSClient实例。

ossclient调用Bucket方法获取bucket。

上传文件

前端传输文件使用FormFile()接收,能够获得一个*multipart.FileHeader类型的变量

file,err:=c.FormFile("xxx")

创建上传文件方法,将*multipart.FileHeader类型变量作为参数之一。

func UploadHandler(UserId int64, title string, file *multipart.FileHeader) (uploadPath string, err error) {
    f, err := file.Open()
    if err != nil {
       log.Fatal("接收文件失败", err)
       return "", err
    }
    uploadFileName := strconv.FormatInt(UserId, 10) + "-" + title + "-" + strconv.FormatInt(time.Now().Unix(), 10) + path.Ext(file.Filename)
    fmt.Println(uploadFileName)
    // 上传文件。
    err = bucket.PutObject(uploadFileName, f)
    if err != nil {
       handleError(err)
       return "", err
    }
    return uploadFileName, nil
}

file.Open()打开文件。然后bucket调用PutObject方法,流式上传文件。参数1为上传文件名,将作为bucket中的全局唯一对象名。注意参数1的文件名建议加上文件后缀,否则文件上传至bucket后再下载将没有默认的文件格式。

此处利用userId+title+时间戳作为文件名能保证其唯一性:userId为 用户的唯一账号,title为用户上传文件的描述,时间戳为上传文件的当前时间。排除了相同描述、相同时间所可能带来的影响。

image-20230828162556964.png

代码运行后到对应bucket中查看文件列表,若有文件则说明上传成功。

访问文件

将文件上传至bucket后,通过对应的url可以访问到对应的文件。若使用oss默认域名则直接访问时,会有以附件形式下载的情况。若需要浏览器直接访问,需使用自定义域名进行访问。

根据bucket的读写权限不同url的形式也会有所不同:

读写权限为私有则访问一个文件的url为类似如下形式:

https://[bucket名称].oss-cn-hangzhou.aliyuncs.com/[文件名+后缀]?Expires=[过期时间戳]&OSSAccessKeyId=[xxxx]

公有读写的url则不包括参数部分:

https://[bucket名称].oss-cn-hangzhou.aliyuncs.com/[文件名+后缀]

但使用公有读写形式时,若不希望其他人对其进行读写操作则必须将自己的bucket名称、accesskey等信息保存好。

image.png

存入数据库

将userId和文件url(甚至只需要唯一文件名)作为表记录存入数据库,用户和文件将会是一对多的关系,这样能够在查询时快速得到某个用户的所有文件。

var user model.User
db.DB.Where("id=?", claims.UserId).First(&user)
// 保存到数据库
newVideo := model.Video{
    Author:     user,
    PlayUrl:    baseUrl + uploadFileName,
    CoverUrl:   baseUrl + uploadFileName,
    UpLoadTime: time.Now().Unix(),
}
db.DB.Create(&newVideo)