golang学习笔记08——如何调用阿里oss sdk实现访问对象存储?

首先确保安装了阿里云 OSS 的 Go SDK:

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

以下是代码示例:

  • 填入你的以下参数,可以直接使用访问:
    • BucketName:存储桶名字
    • Endpoint:访问域名,例如:https://oss-cn-beijing.aliyuncs.com
    • AccessKeyId:oss访问key id
    • AccessKeySecret:oss访问key secret

具体操作:在一个目录下创建两个文件:alioss_facade.go和client.go

    1. alioss_facade.go代码如下:
package alioss

import (
	"context"
	"github.com/aliyun/aliyun-oss-go-sdk/oss"
	"time"
)

const GTimeout = time.Hour // 全局默认过期时间 1小时

var Client = new(client)

func (c *client) Init() error {
	c.BucketName = "你的存储桶名字"
	c.Endpoint = "你的访问域名,例如:https://oss-cn-beijing.aliyuncs.com"
	c.AccessKeyId = "你的oss访问key id"
	c.AccessKeySecret = "你的oss访问key secret"

	return nil
}

// GenUploadUrl 获取具有文件上传权限的路径临时链接(这个链接就可以给前端访问上传文件)
func (c *client) GenUploadUrl(key string) (*OssSignature, error) {
	ossSignature, err := c.generateOssSignature(c.BucketName, key, GTimeout)
	if err != nil {
		fmt.Printf("GenUploadUrl generateOssSignature err: [%+v]", err)
		return nil, err
	}

	return ossSignature, nil
}

// GetRemoteSignUrl 获取一个指定存储路径的临时访问地址
/*
	key: 从 bucket 名字开始的文件路径
*/
func (c *client) GetRemoteSignUrl(key string) (string, error) {
	if key == "" {
		return "", nil
	}
	bucket, err := c.newClientWithBucket(c.BucketName)
	if err != nil {
		fmt.Printf("GetRemoteSignUrl newClientWithBucket newClient err: [%+v]", err)
		return "", err
	}

	url, err := bucket.SignURL(key, oss.HTTPGet, int64(time.Hour*24)) // 一天有效期
	if err != nil {
		fmt.Printf("GetRemoteSignUrl SignURL err: [%+v]", err)
		return "", err
	}
	return url, nil
}

// GetRemoteSignUrlWithNoError 不以错误的返回指定存储路径的临时访问地址(防止避免在文件不存在时前端提示错误的场景)
func (c *client) GetRemoteSignUrlWithNoError(path string) string {
	if path == "" {
		return ""
	}
	bucket, err := c.newClientWithBucket(c.BucketName)
	if err != nil {
		fmt.Printf("GetRemoteSignUrlWithNoError newClientWithBucket newClient err: [%+v]", err)
		return ""
	}

	url, err := bucket.SignURL(path, oss.HTTPGet, int64(time.Hour*24)) // 一天有效期
	if err != nil {
		fmt.Printf("GetRemoteSignUrlWithNoError SignURL err: [%+v]", err)
		return ""
	}
	return url
}
    1. alioss_facade.go代码如下:
package alioss

import (
	"context"
	"crypto/hmac"
	"crypto/sha1"
	"encoding/json"
	"fmt"
	"github.com/aliyun/aliyun-oss-go-sdk/oss"
	"time"
)

func Base64Encode(str string) string {
	return base64.StdEncoding.EncodeToString([]byte(str))
}

type client struct {
	BucketName      string // 存储桶名称
	Endpoint        string // oss访问域名
	AccessKeyId     string // oss访问key id
	AccessKeySecret string // oss访问key secret
}

func (c *client) newClient() (*oss.Client, error) {
	cli, err := oss.New(c.Endpoint, c.AccessKeyId, c.AccessKeySecret)
	if err != nil {
		fmt.Printf("alioss newClient err: [%+v]", err)
		return nil, err
	}

	return cli, nil
}

func (c *client) newClientWithBucket(bucketName string) (*oss.Bucket, error) {
	cli, err := oss.New(c.Endpoint, c.AccessKeyId, c.AccessKeySecret)
	if err != nil {
		fmt.Printf("alioss newClient err: [%+v]", err)
		return nil, err
	}

	return c.getBucket(cli, bucketName)
}

type OssSignature struct {
	SignUrl     string
	AccessKeyId string `json:"accessKeyId"`
	//Host           string `json:"host"`
	Policy    string `json:"policy"`
	Signature string `json:"signature"`
	//SecurityToken  string `json:"securityToken"`
	//ExpirationTime string `json:"expirationTime"`
}

func generateSignature(message string, key string) string {
	hash := hmac.New(sha1.New, []byte(key))
	hash.Write([]byte(message))
	signature := hash.Sum(nil)
	return Base64Encode(string(signature))
}

func (c *client) generateOssSignature(host, objectName string, expirationTime time.Duration) (*OssSignature, error) {

	// 生成策略
	//policy := fmt.Sprintf(`{"Version":"1","Statement":[{"Action":["oss:PutObject"],"Effect":"Allow","Resource":"acs:oss:%s:%s:%s"}]}`, host, c.BucketName, objectName)
	//policy := fmt.Sprintf(`{"Version":"1","Statement":[{"Action":["oss:PutObject"],"Effect":"Allow","Resource":"acs:oss:*:*:%s"}]}`, host)
	//policy := fmt.Sprintf(`{"expiration": "2034-01-01T12:00:00.000Z","conditions":[["content-length-range", 0, 1048576000]]}]}`)
	//policyB64 := Base64Encode(policy)
	// 生成签名URL
	policyText := map[string]interface{}{
		"expiration": getFullTimeoutZ(expirationTime),
		"conditions": [][]interface{}{
			{"content-length-range", 0, 1048576000},
		},
	}
	policyTextJson, _ := json.Marshal(policyText)
	policy := Base64Encode(string((policyTextJson)))
	// 生成签名
	signature := generateSignature(policy, c.AccessKeySecret)

	return &OssSignature{
		AccessKeyId: c.AccessKeyId,
		Policy:      policy,
		Signature:   signature,
		SignUrl:     fmt.Sprintf("https://%s.oss-cn-beijing.aliyuncs.com", host),	// 生成签名地址
	}, nil
}

func (c *client) getBucket(cli *oss.Client, bucketName string) (*oss.Bucket, error) {
	bucket, err := cli.Bucket(bucketName)
	if err != nil {
		fmt.Printf("alioss getBucket err: [%+v]", err)
		return nil, err
	}
	return bucket, nil
}

func getFullTimeoutZ(expirationTime time.Duration) string {
	return time.Now().Add(expirationTime).Format("2006-01-02T15:04:05.000Z")
}

至此,在你的main方法中,或者业务代码中,调用alioss_facade.go中的对外方法,即可访问或写入存储桶的数据。

关注我看更多有意思的文章哦!👉👉

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值