使用阿里云OSS搭建图床API

在之前做的一个项目中,需要用到图床来暂存一些图像。原本我使用的是 SMMS 图床平台,但是它每分钟只能上传 20 张图片,不能适用于并发场景,而其他的一些图床都会有上传限制,所以我决定使用阿里云 OSS 来搭建一个可供并发场景使用的图床。

1. 购买并配置阿里云 OSS 服务

打开阿里云 https://www.aliyun.com/登录
在这里插入图片描述
在首页搜索框搜索 OSS

在这里插入图片描述
点击立即购买

在这里插入图片描述选择 OSS 资源包,根据自己的需要选择其他的参数

在这里插入图片描述
在控制台的资源管理中找到刚刚购买的 OSS 服务,点击进入 OSS 控制台。

在这里插入图片描述
点击创建 Bucket

在这里插入图片描述
读取权限部分,如果只是自己访问,不需要选择公共读,如果需要改变这个权限,需要在创建Bucket之后,再进行选择。

在这里插入图片描述
在这里插入图片描述
点击右上角头像,点击 AccessKey

在这里插入图片描述
在弹出的窗口中选择使用 RAM 用户 AccessKey

在这里插入图片描述
创建用户

在这里插入图片描述
填写登录名称,选择访问方式。

在这里插入图片描述

创建用户时,会让选择手机号或人脸验证,随便选一个方便的就行。创建完成弹出一个窗口,点击确定。

在这里插入图片描述

创建完成后,会得到 AccessKey ID 和 AccessKey Secret,等下会用到。

在这里插入图片描述

2. 使用Golang SDK 集成 OSS

阿里云官方提供了各种编程语言调用上传的示例:https://help.aliyun.com/zh/oss/?spm=a2c4g.11186623.0.0.e3dc1c65XMpzK6,里面可以找到很全面的编程语言SDK使用指南。

在这里插入图片描述

在这里我将展示一下使用 Golang 搭建 API 的方法,最终实现的目标是能够接收 Base64 编码的图片并上传到 OSS。

首先,安装阿里云的 Go SDK:

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

3. 编写上传图片函数

下面是我参考官方文档编写的 UploadImageToOSS 函数,它接收一个Base64 编码的图片字符串,将其解码并上传到 OSS:

package api

import (
	"backend/settings"
	"bytes"
	"context"
	"crypto/rand"
	"encoding/base64"
	"encoding/hex"
	"fmt"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
	"log"
	"strings"
	"time"
)

// UploadImageToOSS 上传图片的函数
func UploadImageToOSS(base64Image string) (string, error) {
	// 如果 Base64 字符串包含图片前缀,则去除它
	if strings.HasPrefix(base64Image, "data:image") {
		base64Image = strings.Split(base64Image, ",")[1]
	}

	// 解码 Base64 数据
	imageData, err := base64.StdEncoding.DecodeString(base64Image)
	if err != nil {
		return "", fmt.Errorf("failed to decode base64 data: %v", err)
	}

	// 配置 OSS 客户端
	cfg := oss.LoadDefaultConfig().
		WithRegion(settings.Conf.Region).
		WithCredentialsProvider(credentials.NewStaticCredentialsProvider(settings.Conf.AccessKeyID, settings.Conf.AccessKeySecret, ""))
	client := oss.NewClient(cfg)

	// 生成文件名
	objectName := GenerateUniqueFileName("png")

	// 创建上传对象的请求
	request := &oss.PutObjectRequest{
		Bucket: oss.Ptr(settings.Conf.Bucket), // 存储空间名称
		Key:    oss.Ptr(objectName),           // 对象名称
		Body:   bytes.NewReader(imageData),    // 图片数据
	}

	// 上传文件
	_, err = client.PutObject(context.TODO(), request)
	if err != nil {
		return "", fmt.Errorf("failed to upload image to OSS: %v", err)
	}

	// 生成文件的 URL
	url := fmt.Sprintf("%s/%s", settings.Conf.Endpoint, objectName)

	return url, nil
}

// GenerateUniqueFileName 生成唯一的文件名称
func GenerateUniqueFileName(extension string) string {
	// 获取当前时间戳
	timestamp := time.Now().UnixNano()

	// 生成随机字符串
	randomBytes := make([]byte, 8)
	_, err := rand.Read(randomBytes)
	if err != nil {
		log.Fatalf("failed to generate random bytes: %v", err)
	}
	randomString := hex.EncodeToString(randomBytes)

	// 拼接文件名
	return fmt.Sprintf("%d-%s.%s", timestamp, randomString, extension)
}

代码解析

  • Base64 解码: 通过 base64.StdEncoding.DecodeString 将其解码为二进制数据。
  • 配置 OSS 客户端: 使用 oss.LoadDefaultConfig 来加载配置,并使用 credentials.NewStaticCredentialsProvider 设置我们的 AccessKeyIDAccessKeySecret
  • 上传图片: 通过 client.PutObject 方法将图片上传到阿里云 OSS。上传时我们需要指定存储桶名称、文件名称以及文件内容。
  • 生成唯一文件名: 为了避免文件重名,可以通过时间戳和随机字符串来生成一个唯一的文件名。
  • 返回图片 URL: 上传成功后,返回图片在 OSS 上的 URL,客户端可以使用该 URL 显示图片。

4. 配置文件和环境变量

在代码中,backend/settings 是我的后端配置文件,通过 settings.Conf 来读取配置项,以下是一个配置示例:

package settings

import "os"

type Config struct {
	AccessKeyID     string
	AccessKeySecret string
	Region          string
	Endpoint        string
	Bucket          string
}

var Conf Config

func init() {
	Conf.AccessKeyID = os.Getenv("ALIYUN_ACCESS_KEY_ID")
	Conf.AccessKeySecret = os.Getenv("ALIYUN_ACCESS_KEY_SECRET")
	Conf.Region = os.Getenv("ALIYUN_REGION")
	Conf.Endpoint = os.Getenv("ALIYUN_ENDPOINT")
	Conf.Bucket = os.Getenv("ALIYUN_BUCKET")
}

参考资料

  1. 轻松搭建网络图床
  2. Go 上传文件
Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐