Files
quyun/backend/providers/ali/credential.go
2025-04-07 15:15:51 +08:00

124 lines
3.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package ali
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"encoding/json"
"fmt"
"hash"
"io"
"strings"
"time"
"github.com/aliyun/credentials-go/credentials"
"github.com/pkg/errors"
)
func (c *Config) GetToken(path string) (*PolicyToken, error) {
product := "oss"
host := fmt.Sprintf("https://%s.oss-%s.aliyuncs.com", c.Bucket, c.Region)
if c.Host != nil {
host = *c.Host
}
// 设置上传目录
dir := strings.TrimRight(path, "/") + "/"
// callbackUrl为 上传回调服务器的URL请将下面的IP和Port配置为您自己的真实信息。
config := new(credentials.Config).
SetType("access_key").
SetAccessKeyId(c.AccessKeyId).
SetAccessKeySecret(c.AccessKeySecret).
SetPolicy("")
// SetType("ram_role_arn").
// SetRoleArn(os.Getenv("OSS_STS_ROLE_ARN")).
// SetRoleSessionName("Role_Session_Name").
// SetRoleSessionExpiration(3600)
// 根据配置创建凭证提供器
provider, err := credentials.NewCredential(config)
if err != nil {
return nil, errors.Wrap(err, "NewCredential fail")
}
// 从凭证提供器获取凭证
cred, err := provider.GetCredential()
if err != nil {
return nil, errors.Wrap(err, "GetCredential fail")
}
// 构建policy
utcTime := time.Now().UTC()
date := utcTime.Format("20060102")
expiration := utcTime.Add(1 * time.Hour)
policyMap := map[string]any{
"expiration": expiration.Format("2006-01-02T15:04:05.000Z"),
"conditions": []any{
map[string]string{"bucket": c.Bucket},
map[string]string{"x-oss-signature-version": "OSS4-HMAC-SHA256"},
map[string]string{"x-oss-credential": fmt.Sprintf("%v/%v/%v/%v/aliyun_v4_request", *cred.AccessKeyId, date, c.Region, product)},
map[string]string{"x-oss-date": utcTime.Format("20060102T150405Z")},
map[string]string{"x-oss-security-token": *cred.SecurityToken},
},
}
// 将policy转换为 JSON 格式
policy, err := json.Marshal(policyMap)
if err != nil {
return nil, errors.Wrap(err, "json.Marshal fail")
}
// 构造待签名字符串StringToSign
stringToSign := base64.StdEncoding.EncodeToString([]byte(policy))
hmacHash := func() hash.Hash { return sha256.New() }
// 构建signing key
signingKey := "aliyun_v4" + *cred.AccessKeySecret
h1 := hmac.New(hmacHash, []byte(signingKey))
io.WriteString(h1, date)
h1Key := h1.Sum(nil)
h2 := hmac.New(hmacHash, h1Key)
io.WriteString(h2, c.Region)
h2Key := h2.Sum(nil)
h3 := hmac.New(hmacHash, h2Key)
io.WriteString(h3, product)
h3Key := h3.Sum(nil)
h4 := hmac.New(hmacHash, h3Key)
io.WriteString(h4, "aliyun_v4_request")
h4Key := h4.Sum(nil)
// 生成签名
h := hmac.New(hmacHash, h4Key)
io.WriteString(h, stringToSign)
signature := hex.EncodeToString(h.Sum(nil))
var callbackParam CallbackParam
callbackParam.CallbackUrl = c.CallbackURL
callbackParam.CallbackBody = "filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}"
callbackParam.CallbackBodyType = "application/x-www-form-urlencoded"
callback_str, err := json.Marshal(callbackParam)
if err != nil {
fmt.Println("callback json err:", err)
}
callbackBase64 := base64.StdEncoding.EncodeToString(callback_str)
// 构建返回给前端的表单
return &PolicyToken{
Policy: stringToSign,
SecurityToken: *cred.SecurityToken,
SignatureVersion: "OSS4-HMAC-SHA256",
Credential: fmt.Sprintf("%v/%v/%v/%v/aliyun_v4_request", *cred.AccessKeyId, date, c.Region, product),
Date: utcTime.UTC().Format("20060102T150405Z"),
Signature: signature,
Host: host, // 返回 OSS 上传地址
Dir: dir, // 返回上传目录
Callback: callbackBase64, // 返回上传回调参数
}, nil
}