前言
最近学习使用对象存储,自然要学习一下 Amazon S3
,同时最近学了一下 Golang,简单记录一下学习使用 AWS SDK for Go V2 生成文件预签名 URL,
预签名:有些时候需要给别人访问对象存储中的对象,又不想给对方桶的权限来访问,就可以通过生成预签名 URL 给别人临时访问对象。官方目前是有两个签名版本 SigV2-带参数&Expires
-1 年 和 SigV4 带参数-&X-Amz-Expires
-7 天,考虑到安全性和使用效率等因素,目前官方已停止 SigV2 版本的支持。
实操
首先创建 S3 Client
对象,在写代码的过程中,我发现 Golang 的 SDK V2 版本和其他语言包括 Go 的 V1 版本在创建 client 对象的时候都有不小的区别,我写的仅作参考
针对自建的对象存储服务器,使用endpoint
时注意UsePathStyle
为true
,不然会出现http://{bucket}.{endpoint}
错误
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
func GetClient(accesskey, secretkey, endpoint string) (*s3.Client, error) {
cfg, err := config.LoadDefaultConfig(
context.TODO(),
config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(accesskey, secretkey, "")),
// 已弃用
// config.WithEndpointResolver(
// aws.EndpointResolverFunc(func(service, region string) (aws.Endpoint, error) {
// return aws.Endpoint{URL: endpoint}, nil
// })),
config.WithEndpointResolverWithOptions(
aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
return aws.Endpoint{URL: endpoint}, nil
})),
config.WithRegion("us-east-1"),
)
if err != nil {
return nil, err
}
client := s3.NewFromConfig(cfg, func(o *s3.Options) {
o.UsePathStyle = true
o.EndpointOptions.DisableHTTPS = true
})
return client, nil
}
|
如下是主要主要代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
type S3PresignGetObjectAPI interface {
PresignGetObject(
ctx context.Context,
params *s3.GetObjectInput,
optFns ...func(*s3.PresignOptions)) (*v4.PresignedHTTPRequest, error)
}
func GetPresignedURL(c context.Context, api S3PresignGetObjectAPI, input *s3.GetObjectInput) (*v4.PresignedHTTPRequest, error) {
return api.PresignGetObject(c, input)
}
// 获取预签名的 url
func GetObjectUrl(client *s3.Client, bucket string, key string) string {
input := &s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
}
psClient := s3.NewPresignClient(client)
resp, err := GetPresignedURL(context.TODO(), psClient, input)
if err != nil {
return ("get url err: " + err.Error())
}
return resp.URL
}
|
参考