使用go语言实现的阿里云对象存储签名直传

先前写过阿里云oss签名直传,使用的是java。后来由于使用了golang重写,于是就有了使用golang实现的签名直传。golang版与java版一致,只不过换成了golang的oss sdk。

第一步 引用阿里云oss golang sdk

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

第二步 最好创建阿里云client以备用

	client, err := oss.New(api.Conf.EndPoint, api.Conf.AccessKey, api.Conf.SecretKey)

参数有EndPoint AccessKey SecretKey

第三步 通过secret 获取签名

// ConfigStruct {"expiration":"2023-01-12T07:59:00.678Z","conditions":[["content-length-range",0,104857600],["starts-with","$key","12345"],{"key":"12345/23.txt"}]}
// 签名内容的json格式
type ConfigStruct struct {
	Expiration string `json:"expiration"`
	Conditions []any  `json:"conditions"`
}

type CallbackParam struct {
	CallbackUrl      string `json:"callbackUrl"`
	CallbackBody     string `json:"callbackBody"`
	CallbackBodyType string `json:"callbackBodyType"`
}


// getPolicyToken 获取预签名参数
func getPolicyToken(accessKey, accessSecret, hostWithBucket, pathPrefix, fullKey, callBackUrl, fileId string, expireTime int64) PolicyToken {
	
    // 计算上传签名的有效时间
    now := time.Now().Unix()
	expire_end := now + expireTime
	var tokenExpire = time.Unix(expire_end, 0).UTC().Format("2006-01-02T15:04:05Z")

	//create post policy json 大至最终结构如下
	// {"expiration":"2023-01-12T07:59:00.678Z","conditions":[["content-length-range",0,104857600],["starts-with","$key","12345"],{"key":"12345/23.txt"}]}
	var config ConfigStruct
	config.Expiration = tokenExpire
	{
		// starts-with key以什么开头,用于限制上传的key的开头字符串
		var condition []string
		condition = append(condition, "starts-with") // starts-with range exact
		condition = append(condition, "$key")        // key Expires Content-Encoding Content-Disposition Content-Type Cache-Control content-length-range success_action_redirect success_action_status  x-oss-meta- x-oss-server-side-
		condition = append(condition, pathPrefix)
		config.Conditions = append(config.Conditions, condition)
	}
	{
		// 长度限制 content-length-range 0-100m 用于限制上传的文件的大小
		var condition []any
		condition = append(condition, "content-length-range") // starts-with range exact
		condition = append(condition, 0)
		condition = append(condition, 104857600)
		config.Conditions = append(config.Conditions, condition)
	}
	{
		// key 限制 用于限制上传的key本身的值 与上边限制开头功能重复
		var condition = map[string]string{}
		condition["key"] = fullKey
		config.Conditions = append(config.Conditions, condition)
	}

	//calucate signature Policy: struct->jsonStr->bytes->base64
    // 结果的转换 Signature: struct->jsonStr->bytes->base64->sha1[with oss secret]->base64
	result, err := json.Marshal(config)
	debyte := base64.StdEncoding.EncodeToString(result)
	h := hmac.New(func() hash.Hash { return sha1.New() }, []byte(accessSecret))
	io.WriteString(h, debyte)
	signedStr := base64.StdEncoding.EncodeToString(h.Sum(nil))

    // 回调地址设置 Callback: json->bytes->base64
	var callbackParam CallbackParam
	callbackParam.CallbackUrl = callBackUrl
	callbackParam.CallbackBody = "filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}&id=" + fileId
	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)

    // 计算完成 组合返回结果
	var policyToken PolicyToken
	policyToken.AccessKeyId = accessKey
	policyToken.Host = hostWithBucket
	policyToken.Expire = expire_end
	policyToken.Signature = string(signedStr)
	policyToken.Directory = pathPrefix
	policyToken.Policy = string(debyte)
	policyToken.Callback = string(callbackBase64)
	return policyToken
}

第四步 在前端上传文件

  以uniapp为例

var uploadTask = uni.uploadFile({
    url: res.host, // 返回参数中带桶名的上传地址 如 https://bucketname.beijing.alioss.com
    filePath: file.path, // 从相册中选择的地址,小程序应该是个文件临时地址
    name: 'file', // from中文件名为file,一定要填file,不然阿里OSS不认
    header: {},
    formData: {
        'key': res.key, // 返回签名参数中的key
        'policy': res.policy, // 返回签名参数中的policy
         'OSSAccessKeyId': res.accessId, // 返回参数中的的accesskey
         'success_action_status': '200', //如果不设置success_action_status为200,文件上传成功后则返回204状态码。
          'signature': res.signature, // 返回参数中的上传签名
          "callback": res.callback // 返回参数中的回调参数
     },
    success: (uploadFileRes) => {
        // 上传成功回调方法
     })
    }
});

注意

在上传时multiform里要把file放在最后把key放在最前

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

独杆小蓬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值