oss.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. package services
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "eta/eta_mini_crm_ht/utils"
  6. "fmt"
  7. "time"
  8. "github.com/aliyun/aliyun-oss-go-sdk/oss"
  9. "github.com/aliyun/alibaba-cloud-sdk-go/services/sts"
  10. )
  11. type STSToken struct {
  12. AccessKeyId string
  13. AccessKeySecret string
  14. SecurityToken string
  15. ExpiredTime string
  16. RegionId string
  17. Bucketname string
  18. Endpoint string
  19. Imghost string
  20. }
  21. type OssClient interface {
  22. UploadFile(string, string, string) (string, error)
  23. GetUploadToken() (OssToken, error)
  24. }
  25. func NewOssClient() OssClient {
  26. switch utils.ObjectStorageClient {
  27. case utils.STORAGESOURCE_OSS_NAME:
  28. return new(AliOss)
  29. default:
  30. // 默认使用minio
  31. return new(MinioOss)
  32. }
  33. }
  34. // OssToken 此处为了兼容前端那边所以有重复的
  35. type OssToken struct {
  36. AccessKeyId string
  37. SecretKeyId string
  38. RegionId string
  39. Bucketname string
  40. Endpoint string
  41. ImgHost string
  42. UseSSL string
  43. Port string
  44. //AccessKeyId string
  45. AccessKeySecret string
  46. SecurityToken string
  47. ExpiredTime string
  48. //RegionId string
  49. //Bucketname string
  50. //Endpoint string
  51. Imghost string
  52. S3ForceStyle bool
  53. S3Protocol string
  54. }
  55. // GetOssSTSToken 获取STSToken
  56. func GetOssSTSToken() (item *STSToken, err error) {
  57. defer func() {
  58. if err != nil {
  59. utils.FileLog.Info(err.Error())
  60. }
  61. }()
  62. item = new(STSToken)
  63. // 获取缓存中的Token
  64. recent, _ := utils.Rc.RedisString(utils.STSTokenCacheKey)
  65. if recent != "" {
  66. lastToken := new(STSToken)
  67. if e := json.Unmarshal([]byte(recent), &lastToken); e != nil {
  68. err = errors.New("GetOssSTSToken lastToken Unmarshal Err: " + e.Error())
  69. return
  70. }
  71. // 未防止正在上传大文件时Token过期, 将判定的过期时间提前10分钟
  72. afterTime := time.Now().Local().Add(10 * time.Minute)
  73. expired, e := time.ParseInLocation(utils.FormatDateTime, lastToken.ExpiredTime, time.Local)
  74. if e != nil {
  75. err = errors.New("GetOssSTSToken expiredTime Parse Err: " + e.Error())
  76. return
  77. }
  78. if expired.After(afterTime) {
  79. item.AccessKeyId = lastToken.AccessKeyId
  80. item.AccessKeySecret = lastToken.AccessKeySecret
  81. item.SecurityToken = lastToken.SecurityToken
  82. item.ExpiredTime = lastToken.ExpiredTime
  83. item.RegionId = utils.RegionId
  84. item.Bucketname = utils.Bucketname
  85. item.Endpoint = utils.Imghost
  86. item.Imghost = utils.Imghost
  87. return
  88. }
  89. }
  90. // 已过期则获取新的token
  91. newToken, e := NewSTSToken()
  92. if e != nil {
  93. err = errors.New("GetOssSTSToken NewSTSToken Err: " + e.Error())
  94. return
  95. }
  96. newTokenJson, e := json.Marshal(newToken)
  97. if e != nil {
  98. err = errors.New("GetOssSTSToken NewToken JSON Err: " + e.Error())
  99. return
  100. }
  101. // 覆盖缓存
  102. if e := utils.Rc.Put(utils.STSTokenCacheKey, newTokenJson, time.Hour); e != nil {
  103. err = errors.New("GetOssSTSToken SetRedis Err: " + e.Error())
  104. return
  105. }
  106. item = newToken
  107. return
  108. }
  109. // NewSTSToken 获取一个新的STSToken
  110. func NewSTSToken() (item *STSToken, err error) {
  111. defer func() {
  112. if err != nil {
  113. utils.FileLog.Info(err.Error())
  114. }
  115. }()
  116. item = new(STSToken)
  117. client, e := sts.NewClientWithAccessKey("cn-shanghai", utils.RAMAccessKeyId, utils.RAMAccessKeySecret)
  118. if e != nil {
  119. err = errors.New("NewSTSToken NewClient Err: " + e.Error())
  120. return
  121. }
  122. request := sts.CreateAssumeRoleRequest()
  123. request.Scheme = utils.AliStsScheme
  124. request.RegionId = utils.RegionId
  125. request.RoleArn = utils.RoleArn
  126. now := time.Now().Format(utils.FormatDateTimeUnSpace)
  127. request.RoleSessionName = utils.RoleSessionName + now
  128. request.DurationSeconds = "3600"
  129. request.ConnectTimeout = 300 * time.Second
  130. request.ReadTimeout = 300 * time.Second
  131. response, e := client.AssumeRole(request)
  132. if e != nil {
  133. err = errors.New("NewSTSToken AssumeRole Err: " + e.Error())
  134. return
  135. }
  136. if response != nil {
  137. item.AccessKeyId = response.Credentials.AccessKeyId
  138. item.AccessKeySecret = response.Credentials.AccessKeySecret
  139. item.SecurityToken = response.Credentials.SecurityToken
  140. t, _ := time.Parse(time.RFC3339, response.Credentials.Expiration)
  141. expiration := t.In(time.Local)
  142. item.ExpiredTime = expiration.Format(utils.FormatDateTime)
  143. item.RegionId = utils.RegionId
  144. item.Bucketname = utils.Bucketname
  145. item.Endpoint = utils.Imghost
  146. item.Imghost = utils.Imghost
  147. }
  148. return
  149. }
  150. type AliOss struct{}
  151. // UploadFile 上传文件
  152. func (m *AliOss) UploadFile(fileName, filePath, savePath string) (string, error) {
  153. if utils.AccessKeyId == `` {
  154. return "0", errors.New("阿里云信息未配置")
  155. }
  156. client, err := oss.New(utils.Endpoint, utils.AccessKeyId, utils.AccessKeySecret)
  157. if err != nil {
  158. return "1", err
  159. }
  160. bucket, err := client.Bucket(utils.Bucketname)
  161. if err != nil {
  162. return "2", err
  163. }
  164. path := savePath
  165. if savePath == "" {
  166. path = utils.UploadDir + time.Now().Format("200601/20060102/") + fileName
  167. }
  168. err = bucket.PutObjectFromFile(path, filePath)
  169. if err != nil {
  170. return "3", err
  171. }
  172. resourceUrl := utils.Imghost + path
  173. return resourceUrl, err
  174. }
  175. func (m *AliOss) GetUploadToken() (token OssToken, err error) {
  176. stsToken, e := GetOssSTSToken()
  177. if e != nil {
  178. err = fmt.Errorf("GetOssSTSToken err: %s", e.Error())
  179. return
  180. }
  181. token.AccessKeyId = stsToken.AccessKeyId
  182. token.AccessKeySecret = stsToken.AccessKeySecret
  183. token.SecurityToken = stsToken.SecurityToken
  184. token.ExpiredTime = stsToken.ExpiredTime
  185. token.RegionId = stsToken.RegionId
  186. token.Bucketname = stsToken.Bucketname
  187. token.Endpoint = stsToken.Endpoint
  188. token.Imghost = stsToken.Imghost
  189. return
  190. }