add apis
CI / changes (push) Successful in 1m55s
CI / ad (push) Successful in 0s
CI / admin (push) Successful in 1s
CI / bff (push) Successful in 32s
CI / chore (push) Failing after 9s
CI / equipment (push) Successful in 0s
CI / express (push) Successful in 0s
CI / factory (push) Successful in 0s
CI / message (push) Successful in 0s
CI / order (push) Successful in 0s
CI / payment (push) Successful in 0s
CI / percutaneous (push) Successful in 1s
CI / product (push) Successful in 0s
CI / record (push) Successful in 1s
CI / sale (push) Successful in 0s
CI / support (push) Successful in 0s
CI / task (push) Successful in 0s
CI / user (push) Successful in 1s
CI / water (push) Successful in 0s
CI / wecom (push) Successful in 0s
CI / changes (push) Successful in 1m55s
CI / ad (push) Successful in 0s
CI / admin (push) Successful in 1s
CI / bff (push) Successful in 32s
CI / chore (push) Failing after 9s
CI / equipment (push) Successful in 0s
CI / express (push) Successful in 0s
CI / factory (push) Successful in 0s
CI / message (push) Successful in 0s
CI / order (push) Successful in 0s
CI / payment (push) Successful in 0s
CI / percutaneous (push) Successful in 1s
CI / product (push) Successful in 0s
CI / record (push) Successful in 1s
CI / sale (push) Successful in 0s
CI / support (push) Successful in 0s
CI / task (push) Successful in 0s
CI / user (push) Successful in 1s
CI / water (push) Successful in 0s
CI / wecom (push) Successful in 0s
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"hash"
|
||||
"io"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"lone-services/pkg/utils"
|
||||
chore "lone-services/rpc/chore/pb"
|
||||
"lone-services/services/chore/internal/svc"
|
||||
|
||||
"github.com/alibabacloud-go/tea/tea"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type OssSignatureLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
type MiniOssSignature struct {
|
||||
Policy string `json:"policy"`
|
||||
SecurityToken string `json:"security_token"`
|
||||
XOssSignatureVersion string `json:"x_oss_signature_version"`
|
||||
XOssCredential string `json:"x_oss_credential"`
|
||||
XOssDate string `json:"x_oss_date"`
|
||||
Signature string `json:"signature"`
|
||||
Host string `json:"host"`
|
||||
Dir string `json:"dir"`
|
||||
Bucket string `json:"bucket"`
|
||||
CdnHost string `json:"cdn_host"`
|
||||
Expire int64 `json:"expire"`
|
||||
}
|
||||
|
||||
func NewOssSignatureLogic(ctx context.Context, svcCtx *svc.ServiceContext) *OssSignatureLogic {
|
||||
return &OssSignatureLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
func (l *OssSignatureLogic) OssSignature(in *chore.OssSignatureReq) (*chore.Response, error) {
|
||||
accessKeyId := utils.GetConfigString("oss.accessKeyId")
|
||||
accessKeySecret := utils.GetConfigString("oss.accessKeySecret")
|
||||
roleArn := utils.GetConfigString("oss.roleArn")
|
||||
roleSessionName := utils.GetConfigString("oss.roleSessionName")
|
||||
region := utils.GetConfigString("oss.region")
|
||||
bucket := utils.GetConfigString("oss.bucketName")
|
||||
dir := utils.GetConfigString("oss.dir")
|
||||
endpoint := utils.GetConfigString("oss.endpoint")
|
||||
cdnHost := utils.GetConfigString("oss.host")
|
||||
expireSec := int64(utils.GetConfigInt("oss.expireSeconds"))
|
||||
|
||||
signRegion := strings.TrimPrefix(region, "oss-")
|
||||
stsEndpoint := "sts." + signRegion + ".aliyuncs.com"
|
||||
|
||||
client, err := CreateClient(tea.String(accessKeyId), tea.String(accessKeySecret), tea.String(stsEndpoint))
|
||||
if err != nil {
|
||||
l.Errorf("create STS client: %v", err)
|
||||
return failResponse(utils.Fail), nil
|
||||
}
|
||||
resp, err := AssumeRole(client, roleArn, roleSessionName, expireSec)
|
||||
if err != nil {
|
||||
l.Errorf("AssumeRole: %v", err)
|
||||
return failResponse(utils.Fail), nil
|
||||
}
|
||||
if resp == nil || resp.Body == nil || resp.Body.Credentials == nil {
|
||||
l.Errorf("AssumeRole empty credentials")
|
||||
return failResponse(utils.Fail), nil
|
||||
}
|
||||
|
||||
cred := resp.Body.Credentials
|
||||
stsAccessKeyId := tea.StringValue(cred.AccessKeyId)
|
||||
stsAccessKeySecret := tea.StringValue(cred.AccessKeySecret)
|
||||
securityToken := tea.StringValue(cred.SecurityToken)
|
||||
|
||||
utcNow := time.Now().UTC()
|
||||
date := utcNow.Format("20060102")
|
||||
xOssDate := utcNow.Format("20060102T150405Z")
|
||||
expiration := utcNow.Add(time.Duration(expireSec) * time.Second)
|
||||
credential := fmt.Sprintf("%s/%s/%s/oss/aliyun_v4_request", stsAccessKeyId, date, signRegion)
|
||||
|
||||
policyMap := map[string]any{
|
||||
"expiration": expiration.Format("2006-01-02T15:04:05.000Z"),
|
||||
"conditions": []any{
|
||||
map[string]string{"bucket": bucket},
|
||||
map[string]string{"x-oss-signature-version": "OSS4-HMAC-SHA256"},
|
||||
map[string]string{"x-oss-credential": credential},
|
||||
map[string]string{"x-oss-date": xOssDate},
|
||||
map[string]string{"x-oss-security-token": securityToken},
|
||||
[]any{"starts-with", "$key", dir},
|
||||
},
|
||||
}
|
||||
policyJSON, err := json.Marshal(policyMap)
|
||||
if err != nil {
|
||||
l.Errorf("marshal policy: %v", err)
|
||||
return failResponse(utils.Fail), nil
|
||||
}
|
||||
stringToSign := base64.StdEncoding.EncodeToString(policyJSON)
|
||||
signature := ossV4Sign(stsAccessKeySecret, date, signRegion, stringToSign)
|
||||
|
||||
out := MiniOssSignature{
|
||||
Policy: stringToSign,
|
||||
SecurityToken: securityToken,
|
||||
XOssSignatureVersion: "OSS4-HMAC-SHA256",
|
||||
XOssCredential: credential,
|
||||
XOssDate: xOssDate,
|
||||
Signature: signature,
|
||||
Host: strings.TrimRight(endpoint, "/"),
|
||||
Dir: dir,
|
||||
Bucket: bucket,
|
||||
CdnHost: strings.TrimRight(cdnHost, "/"),
|
||||
Expire: expiration.Unix(),
|
||||
}
|
||||
return okResponse(out), nil
|
||||
}
|
||||
|
||||
func ossV4Sign(accessKeySecret, date, region, stringToSign string) string {
|
||||
hmacHash := func() hash.Hash { return sha256.New() }
|
||||
|
||||
h1 := hmac.New(hmacHash, []byte("aliyun_v4"+accessKeySecret))
|
||||
_, _ = io.WriteString(h1, date)
|
||||
h1Key := h1.Sum(nil)
|
||||
|
||||
h2 := hmac.New(hmacHash, h1Key)
|
||||
_, _ = io.WriteString(h2, region)
|
||||
h2Key := h2.Sum(nil)
|
||||
|
||||
h3 := hmac.New(hmacHash, h2Key)
|
||||
_, _ = io.WriteString(h3, "oss")
|
||||
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)
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
@@ -33,6 +33,12 @@ func (s *ChoreServer) Upload(ctx context.Context, in *chore.UploadReq) (*chore.R
|
||||
return l.Upload(in)
|
||||
}
|
||||
|
||||
// 微信小程序直传 OSS 所需的 PostObject V4 签名参数
|
||||
func (s *ChoreServer) OssSignature(ctx context.Context, in *chore.OssSignatureReq) (*chore.Response, error) {
|
||||
l := logic.NewOssSignatureLogic(ctx, s.svcCtx)
|
||||
return l.OssSignature(in)
|
||||
}
|
||||
|
||||
func (s *ChoreServer) Test(ctx context.Context, in *chore.TestReq) (*chore.Response, error) {
|
||||
l := logic.NewTestLogic(ctx, s.svcCtx)
|
||||
return l.Test(in)
|
||||
|
||||
Reference in New Issue
Block a user