SdkClient.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. package utils
  2. import (
  3. "crypto/hmac"
  4. "crypto/sha256"
  5. "encoding/hex"
  6. "encoding/json"
  7. "fmt"
  8. "git.sxidc.com/student-physical-examination/contract_lock_sdk/commons"
  9. "git.sxidc.com/student-physical-examination/contract_lock_sdk/config"
  10. "git.sxidc.com/student-physical-examination/contract_lock_sdk/constant"
  11. "git.sxidc.com/student-physical-examination/contract_lock_sdk/http"
  12. "github.com/tjfoc/gmsm/sm3"
  13. "io/ioutil"
  14. "log"
  15. "os"
  16. "reflect"
  17. "strconv"
  18. "strings"
  19. )
  20. type SdkClient struct {
  21. ServerUrl string
  22. AccessToken string
  23. AccessSecret string
  24. SignatureVersion string
  25. TraceId string
  26. IdempotentToken string
  27. EnableNonce bool
  28. CustomHeaders map[string]string
  29. ProxyInfo *config.ProxyInfo
  30. }
  31. func NewSdkClient(serverUrl string, accessToken string, accessSecret string) *SdkClient {
  32. sdkClient := SdkClient{
  33. ServerUrl: serverUrl,
  34. AccessToken: accessToken,
  35. AccessSecret: accessSecret,
  36. SignatureVersion: commons.MD5,
  37. EnableNonce: true,
  38. }
  39. return &sdkClient
  40. }
  41. // 返回字符串
  42. func (sdk *SdkClient) ServiceAsString(request SdkRequest) string {
  43. return sdk.SdkRequest(request)
  44. }
  45. // 只返回code、message
  46. func (sdk *SdkClient) Service(request SdkRequest) *SdkResponse {
  47. jsonStr := sdk.SdkRequest(request)
  48. response := SdkResponse{}
  49. var jsonObj map[string]interface{}
  50. if err := json.Unmarshal([]byte(jsonStr), &jsonObj); err != nil {
  51. log.Println("Error parsing JSON:", err)
  52. return &response
  53. }
  54. codeStr := fmt.Sprintf("%v", jsonObj["code"])
  55. code, _ := strconv.ParseInt(codeStr, 10, 64)
  56. response.Code = code
  57. response.Message = jsonObj["message"].(string)
  58. response.ResultStream = false
  59. return &response
  60. }
  61. // code、message、result(包括基本类型和对象类型和对象数组类型)
  62. func (sdk *SdkClient) ServiceAsModel(request SdkRequest, obj interface{}) *SdkResponse {
  63. jsonStr := sdk.SdkRequest(request)
  64. response := SdkResponse{}
  65. var jsonObj map[string]interface{}
  66. if err := json.Unmarshal([]byte(jsonStr), &jsonObj); err != nil {
  67. log.Println("Error parsing JSON:", err)
  68. return &response
  69. }
  70. codeStr := fmt.Sprintf("%v", jsonObj["code"])
  71. code, _ := strconv.ParseInt(codeStr, 10, 64)
  72. response.Code = code
  73. response.Message = jsonObj["message"].(string)
  74. response.ResultStream = false
  75. delete(jsonObj, "code")
  76. delete(jsonObj, "message")
  77. num := len(jsonObj)
  78. // 返回结果只存在code、message
  79. if num == 0 {
  80. return &response
  81. }
  82. //处理返回值为code、message、result(基础类型)
  83. basicType := isBasicType(obj)
  84. if basicType {
  85. // 检查是否存在某个键
  86. value, exists := constant.BASICS_TYPE[request.GetUrl()]
  87. if exists {
  88. result, _ := jsonObj[value]
  89. response.Result = result
  90. } else {
  91. for _, result := range jsonObj {
  92. response.Result = result
  93. }
  94. }
  95. return &response
  96. }
  97. //处理返回值为code、message、result(对象类型)
  98. // 返回结果除去code、message之后,只有一个字段,可能出现的结果如下:
  99. // 1、基本类型
  100. // 2、对象类型
  101. var resultData interface{}
  102. if num == 1 {
  103. for key, value := range jsonObj {
  104. valueType := reflect.ValueOf(value).Kind()
  105. if valueType == reflect.Map {
  106. resultData = value
  107. } else {
  108. flag := commons.IsPropertyExists(obj, key)
  109. if flag {
  110. resultData = jsonObj
  111. }
  112. }
  113. jsonBytes, _ := json.Marshal(resultData)
  114. json.Unmarshal(jsonBytes, obj)
  115. response.Result = obj
  116. return &response
  117. }
  118. }
  119. //处理返回值为code、message、result1(任意类型)、result2(任意类型)【将result1、result2封装为一个对象中的两个字段】
  120. if num > 1 {
  121. fieldName, exists := constant.EXTRA_FIELD[request.GetUrl()]
  122. if exists {
  123. result, _ := jsonObj[fieldName]
  124. switch reflect.TypeOf(result).Kind() {
  125. case reflect.Map:
  126. if resultMap, ok := result.(map[string]interface{}); ok {
  127. for key, value := range jsonObj {
  128. if fieldName != key {
  129. resultMap[key] = value
  130. }
  131. }
  132. resultData = resultMap
  133. }
  134. case reflect.Slice:
  135. if resultList, ok := result.([]interface{}); ok {
  136. for _, value := range resultList {
  137. if resultMap, ok := value.(map[string]interface{}); ok {
  138. for key, value := range jsonObj {
  139. if fieldName != key {
  140. resultMap[key] = value
  141. }
  142. }
  143. }
  144. }
  145. resultData = result
  146. }
  147. }
  148. } else {
  149. resultData = jsonObj
  150. }
  151. }
  152. jsonBytes, _ := json.Marshal(resultData)
  153. json.Unmarshal(jsonBytes, obj)
  154. response.Result = obj
  155. return &response
  156. }
  157. // 文件下载
  158. func (sdk *SdkClient) Download(request SdkRequest, file *os.File) *SdkResponse {
  159. if strings.HasSuffix(sdk.ServerUrl, "/") {
  160. sdk.ServerUrl = sdk.ServerUrl[:len(sdk.ServerUrl)-1]
  161. }
  162. url := sdk.ServerUrl + request.GetUrl()
  163. parameter := request.GetHttpParameter()
  164. header := sdk.buildHttpHeader(parameter)
  165. jsonStr := ""
  166. if parameter.IsJson() {
  167. jsonStr = http.DoDownloadWithJson(url, parameter, header, file, sdk.ProxyInfo)
  168. } else {
  169. jsonStr = http.DoDownload(url, parameter, header, file, sdk.ProxyInfo)
  170. }
  171. response := SdkResponse{}
  172. if len(jsonStr) <= 0 {
  173. response.Code = 0
  174. response.Message = "SUCCESS"
  175. response.ResultStream = true
  176. return &response
  177. }
  178. response.ResultStream = false
  179. var jsonObj map[string]interface{}
  180. if err := json.Unmarshal([]byte(jsonStr), &jsonObj); err != nil {
  181. log.Println("Error parsing JSON:", err)
  182. return &response
  183. }
  184. codeStr := fmt.Sprintf("%v", jsonObj["code"])
  185. code, _ := strconv.ParseInt(codeStr, 10, 64)
  186. response.Code = code
  187. response.Message = jsonObj["message"].(string)
  188. delete(jsonObj, "code")
  189. delete(jsonObj, "message")
  190. num := len(jsonObj)
  191. // 返回结果只存在code、message
  192. if num == 0 {
  193. return &response
  194. }
  195. var resultObj interface{}
  196. for _, result := range jsonObj {
  197. resultObj = result
  198. }
  199. resultData, _ := json.Marshal(resultObj)
  200. reflectObj, exists := constant.STREAM_RESULT[request.GetUrl()]
  201. if exists {
  202. personValue := reflect.New(reflectObj).Elem()
  203. err := json.Unmarshal(resultData, personValue.Addr().Interface())
  204. if err != nil {
  205. fmt.Println("Error unmarshalling JSON:", err)
  206. return &response
  207. }
  208. obj := personValue.Interface()
  209. response.Result = obj
  210. return &response
  211. }
  212. return &response
  213. }
  214. func (sdk *SdkClient) SdkRequest(request SdkRequest) string {
  215. if strings.HasSuffix(sdk.ServerUrl, "/") {
  216. sdk.ServerUrl = sdk.ServerUrl[:len(sdk.ServerUrl)-1]
  217. }
  218. url := sdk.ServerUrl + request.GetUrl()
  219. parameter := request.GetHttpParameter()
  220. header := sdk.buildHttpHeader(parameter)
  221. if parameter.IsJson() {
  222. return http.DoServiceWithJson(url, parameter, header, sdk.ProxyInfo)
  223. }
  224. return http.DoService(url, parameter, header, sdk.ProxyInfo)
  225. }
  226. func (sdk *SdkClient) buildHttpHeader(httpParameter *http.HttpParameter) *http.HttpHeader {
  227. timestamp := commons.GetTimeStamp()
  228. nonce := ""
  229. if sdk.EnableNonce {
  230. nonce = commons.GetUUID()
  231. }
  232. var signature string
  233. if commons.HMACSHA256 == sdk.SignatureVersion {
  234. hmacSignatureList := make([]ParameterBody, 0)
  235. hmacSignatureList = append(hmacSignatureList, NewStringParameter(commons.ACCESS_TOKEN, sdk.AccessToken))
  236. hmacSignatureList = append(hmacSignatureList, NewStringParameter(commons.TIMESTAMP, timestamp))
  237. hmacSignatureList = append(hmacSignatureList, NewStringParameter(commons.NONCE, nonce))
  238. hmacSignatureList = append(hmacSignatureList, NewStringParameter(commons.SIGNATURE_VERSION, sdk.SignatureVersion))
  239. hmacSignatureList = append(hmacSignatureList, NewStringParameter(commons.IDEMPOTENTTOKEN, sdk.IdempotentToken))
  240. hmacSignatureList = append(hmacSignatureList, NewStringParameter(commons.TRACEID, sdk.TraceId))
  241. if httpParameter.IsJson() {
  242. hmacSignatureList = append(hmacSignatureList, NewStringParameter(commons.BODY, httpParameter.JsonParamer()))
  243. } else {
  244. hmacSignatureList = append(hmacSignatureList, NewStringParameter(commons.BODY, ""))
  245. params := httpParameter.Params()
  246. for key, value := range params {
  247. if commons.IsNil(value) {
  248. continue
  249. }
  250. switch t := value.(type) {
  251. case string:
  252. if len(t) != 0 {
  253. hmacSignatureList = append(hmacSignatureList, NewStringParameter(key, fmt.Sprintf("%v", t)))
  254. }
  255. case *int, *int32, *int64:
  256. if f, ok := value.(*int64); ok {
  257. hmacSignatureList = append(hmacSignatureList, NewStringParameter(key, fmt.Sprintf("%d", *f)))
  258. }
  259. case *float32, *float64:
  260. if f, ok := value.(*float64); ok {
  261. hmacSignatureList = append(hmacSignatureList, NewStringParameter(key, fmt.Sprintf("%f", *f)))
  262. }
  263. case *bool:
  264. if f, ok := value.(*bool); ok {
  265. hmacSignatureList = append(hmacSignatureList, NewStringParameter(key, fmt.Sprintf("%t", *f)))
  266. }
  267. default:
  268. hmacSignatureList = append(hmacSignatureList, NewStringParameter(key, fmt.Sprintf("%v", value)))
  269. }
  270. }
  271. files := httpParameter.Files()
  272. for key, file := range files {
  273. defer file.Close()
  274. bytes, _ := ioutil.ReadAll(file)
  275. hmacSignatureList = append(hmacSignatureList, NewBytesParameter(key, bytes))
  276. }
  277. listFiles := httpParameter.ListFiles()
  278. for key, fileList := range listFiles {
  279. for _, file := range fileList {
  280. defer file.Close()
  281. bytes, _ := ioutil.ReadAll(file)
  282. hmacSignatureList = append(hmacSignatureList, NewBytesParameter(key, bytes))
  283. }
  284. }
  285. }
  286. signature = sdk.CalculateSignature(httpParameter.HttpMethod(), hmacSignatureList)
  287. } else if commons.SM3 == sdk.SignatureVersion {
  288. rawSig := sdk.AccessToken + sdk.AccessSecret + timestamp + nonce
  289. hash := sm3.New()
  290. hash.Write([]byte(rawSig))
  291. result := hash.Sum(nil)
  292. signature = hex.EncodeToString(result)
  293. } else {
  294. signature = commons.GetMD5(sdk.AccessToken + sdk.AccessSecret + timestamp + nonce)
  295. }
  296. header := http.HttpHeader{
  297. AccessToken: sdk.AccessToken,
  298. Timestamp: timestamp,
  299. Nonce: nonce,
  300. Signature: signature,
  301. SignatureVersion: sdk.SignatureVersion,
  302. TraceId: sdk.TraceId,
  303. IdempotentToken: sdk.IdempotentToken,
  304. CustomHeaders: sdk.CustomHeaders,
  305. }
  306. return &header
  307. }
  308. func (sdk *SdkClient) CalculateSignature(method string, hmacSignatureList []ParameterBody) string {
  309. SortParameterBody(hmacSignatureList)
  310. mac := hmac.New(sha256.New, []byte(sdk.AccessSecret))
  311. mac.Write([]byte(method))
  312. for _, parameterBody := range hmacSignatureList {
  313. str := commons.CONNECTOR + parameterBody.Name + commons.EQUALSIGN
  314. mac.Write([]byte(str))
  315. if parameterBody.Bytes != nil {
  316. mac.Write(parameterBody.Bytes)
  317. }
  318. }
  319. sum := mac.Sum(nil)
  320. hexMac := make([]byte, len(sum)*2)
  321. hex.Encode(hexMac, sum)
  322. return fmt.Sprintf("%s", hexMac)
  323. }