util.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. /*
  2. * @Descripttion:实名认证
  3. * @version:
  4. * @Author: Neo,Huang
  5. * @Date: 2021-04-17 11:04:16
  6. * @LastEditors: Neo,Huang
  7. * @LastEditTime: 2022-04-12 20:27:43
  8. */
  9. package nppa
  10. import (
  11. "crypto/aes"
  12. "crypto/cipher"
  13. "crypto/rand"
  14. "crypto/sha256"
  15. "encoding/base64"
  16. "encoding/hex"
  17. "encoding/json"
  18. "fmt"
  19. "io"
  20. "io/ioutil"
  21. "log"
  22. "net/http"
  23. "net/url"
  24. "sort"
  25. "strconv"
  26. "strings"
  27. "sync"
  28. "time"
  29. "box-3rdServer/utils"
  30. "github.com/bitly/go-simplejson"
  31. )
  32. type ConfApp struct {
  33. aId int
  34. appId string
  35. appName string
  36. bizId string
  37. secretKey string
  38. }
  39. var mapAidToConf sync.Map
  40. var mapChannelToConf sync.Map
  41. // 初始化
  42. func initConf() {
  43. path := utils.GetConfigPath()
  44. j := utils.LoadJsonFile(path + "NppaAppConfig.json")
  45. tmpMapAidToConf := make(map[int]*ConfApp)
  46. mapAppNameToConf := make(map[string]*ConfApp)
  47. for _, v := range j.MustArray() {
  48. item, _ := v.(map[string]interface{})
  49. val, ok := item["aId"]
  50. if !ok {
  51. continue
  52. }
  53. aId := utils.JsonNumberToInt(val)
  54. conf := &ConfApp{aId: aId}
  55. val, ok = item["appId"]
  56. if ok {
  57. conf.appId = val.(string)
  58. }
  59. val, ok = item["appName"]
  60. if ok {
  61. conf.appName = val.(string)
  62. }
  63. val, ok = item["bizId"]
  64. if ok {
  65. conf.bizId = val.(string)
  66. }
  67. val, ok = item["secretKey"]
  68. if ok {
  69. conf.secretKey = val.(string)
  70. }
  71. tmpMapAidToConf[aId] = conf
  72. mapAppNameToConf[conf.appName] = conf
  73. }
  74. j = utils.LoadJsonFile(path + "NppaChannelConfig.json")
  75. mapChannelToAid := make(map[int]int)
  76. mapChannelToAppName := make(map[int]string)
  77. for _, v := range j.MustArray() {
  78. item, _ := v.(map[string]interface{})
  79. val, ok := item["channel"]
  80. if !ok {
  81. continue
  82. }
  83. channel := utils.JsonNumberToInt(val)
  84. val, ok = item["aId"]
  85. if ok {
  86. mapChannelToAid[channel] = utils.JsonNumberToInt(val)
  87. }
  88. val, ok = item["appName"]
  89. if ok {
  90. mapChannelToAppName[channel] = val.(string)
  91. }
  92. }
  93. mapAidToConf.Range(func(k, v interface{}) bool {
  94. _, ok := tmpMapAidToConf[k.(int)]
  95. if !ok {
  96. mapAidToConf.Delete(k)
  97. }
  98. return true
  99. })
  100. for k, v := range tmpMapAidToConf {
  101. mapAidToConf.Store(k, v)
  102. }
  103. mapTmp := make(map[int]*ConfApp)
  104. for k, v := range mapChannelToAid {
  105. conf, ok := tmpMapAidToConf[v]
  106. if ok {
  107. mapTmp[k] = conf
  108. }
  109. }
  110. mapChannelToConf.Range(func(k, v interface{}) bool {
  111. _, ok := mapTmp[k.(int)]
  112. if !ok {
  113. mapChannelToConf.Delete(k)
  114. }
  115. return true
  116. })
  117. for k, v := range mapTmp {
  118. mapChannelToConf.Store(k, v)
  119. }
  120. }
  121. // 配置更新
  122. func ConfUpdate() {
  123. initConf()
  124. }
  125. // 渠道配置
  126. func ConfGetInfoByAid(aid int) map[string]string {
  127. v, ok := mapAidToConf.Load(aid)
  128. if !ok {
  129. return nil
  130. }
  131. conf := v.(*ConfApp)
  132. info := make(map[string]string)
  133. info["appId"] = conf.appId
  134. info["bizId"] = conf.bizId
  135. info["secretKey"] = conf.secretKey
  136. info["timestamps"] = fmt.Sprintf("%v", time.Now().UnixNano()/1e6)
  137. return info
  138. }
  139. // 渠道配置
  140. func ConfGetInfoByChannel(chn int) map[string]string {
  141. v, ok := mapChannelToConf.Load(chn)
  142. if !ok {
  143. return nil
  144. }
  145. conf := v.(*ConfApp)
  146. info := make(map[string]string)
  147. info["appId"] = conf.appId
  148. info["bizId"] = conf.bizId
  149. info["secretKey"] = conf.secretKey
  150. info["timestamps"] = fmt.Sprintf("%v", time.Now().UnixNano()/1e6)
  151. return info
  152. }
  153. // 创建请求消息body
  154. func MakeRequestBody(m map[string]interface{}, secretKey string) string {
  155. pack, _ := json.Marshal(m)
  156. key, _ := hex.DecodeString(secretKey)
  157. block, err := aes.NewCipher(key)
  158. if err != nil {
  159. return ""
  160. }
  161. aesGcm, err := cipher.NewGCM(block)
  162. if err != nil {
  163. return ""
  164. }
  165. // 向量
  166. nonce := make([]byte, aesGcm.NonceSize())
  167. if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
  168. return ""
  169. }
  170. cipherText := aesGcm.Seal(nonce, nonce, pack, nil)
  171. // encode as base64 string
  172. encoded := base64.StdEncoding.EncodeToString(cipherText)
  173. ret := make(map[string]string)
  174. ret["data"] = encoded
  175. pack, _ = json.Marshal(ret)
  176. return string(pack)
  177. }
  178. // 签名
  179. func MakeRequestSign(heads map[string]string, params map[string]string, body string) string {
  180. var kvs utils.Kvs
  181. kvs = append(kvs, &utils.Kv{Key: "appId", Value: heads["appId"]})
  182. kvs = append(kvs, &utils.Kv{Key: "bizId", Value: heads["bizId"]})
  183. kvs = append(kvs, &utils.Kv{Key: "timestamps", Value: heads["timestamps"]})
  184. for k, v := range params {
  185. kvs = append(kvs, &utils.Kv{Key: k, Value: url.QueryEscape(v)})
  186. }
  187. sort.Sort(kvs)
  188. key := ""
  189. for i := 0; i < kvs.Len(); i++ {
  190. key += kvs[i].Key + kvs[i].Value
  191. }
  192. strEncode := heads["secretKey"] + key + body
  193. h2 := sha256.New()
  194. h2.Write([]byte(strEncode))
  195. hashed := h2.Sum(nil)
  196. sign := hex.EncodeToString(hashed)
  197. // log.Println(fmt.Sprintf("MakeRequestSign strEncode[%s] sign[%s]", strEncode, sign))
  198. return sign
  199. }
  200. // 请求 网络游戏防沉迷实名认证系统
  201. func Send2Nppa(method string, url string, heads map[string]string, params map[string]string, body string) ([]byte, error) {
  202. if len(params) > 0 {
  203. url += "?"
  204. for k, v := range params {
  205. url += k + "=" + v + "&"
  206. }
  207. url = url[:len(url)-1]
  208. }
  209. req, err1 := http.NewRequest(method, url, strings.NewReader(body))
  210. if err1 != nil {
  211. return nil, err1
  212. }
  213. req.Header.Set("Content-Type", "application/json;charset=utf-8")
  214. req.Header.Set("appId", heads["appId"])
  215. req.Header.Set("bizId", heads["bizId"])
  216. req.Header.Set("timestamps", heads["timestamps"])
  217. req.Header.Set("sign", heads["sign"])
  218. client := &http.Client{}
  219. resp, err2 := client.Do(req)
  220. if err2 != nil {
  221. return nil, err2
  222. }
  223. defer resp.Body.Close()
  224. return ioutil.ReadAll(resp.Body)
  225. }
  226. // 测试签名
  227. func TestSign() string {
  228. mapBody := make(map[string]interface{})
  229. mapBody["id"] = "test-id"
  230. mapBody["name"] = "test-name"
  231. mapInfo := make(map[string]string)
  232. mapInfo["appId"] = "test-appId"
  233. mapInfo["bizId"] = "test-bizId"
  234. mapInfo["secretKey"] = "2836e95fcd10e04b0069bb1ee659955b"
  235. mapInfo["timestamps"] = "1584949895758"
  236. body := MakeRequestBody(mapBody, mapInfo["secretKey"])
  237. sign := MakeRequestSign(mapInfo, nil, body)
  238. // log.Println(fmt.Sprintf("TestSign sign[%s]", sign))
  239. return sign
  240. }
  241. // 获取玩家嘉米实名认证信息
  242. func GetJiamiIdInfo(uid int) map[string]string {
  243. project := utils.GetProject()
  244. idInfo := make(map[string]string)
  245. // 麻将
  246. if project == "mahjong" {
  247. idInfo = GetMahjongIdInfo(uid)
  248. } else if project == "H5ddz" {
  249. idInfo = GetH5ddzIdInfo(uid)
  250. }
  251. return idInfo
  252. }
  253. func GetMahjongIdInfo(uid int) map[string]string {
  254. idInfo := make(map[string]string)
  255. idInfo["name"] = utils.GetPlayerInfoFromRedis(uid, "jmIDName")
  256. idInfo["idNum"] = utils.GetPlayerInfoFromRedis(uid, "jmIDCard")
  257. idInfo["chn"] = utils.GetPlayerInfoFromRedis(uid, "channel")
  258. return idInfo
  259. }
  260. func GetH5ddzIdInfo(uid int) map[string]string {
  261. idInfo := make(map[string]string)
  262. info := utils.GetPlayerInfoFromRedis(uid, "info")
  263. j, err := simplejson.NewJson([]byte(info))
  264. if err != nil {
  265. log.Println("GetH5ddzIdInfo err:", err)
  266. return idInfo
  267. }
  268. idInfo["name"], _ = j.Get("antiAddiData").Get("identityName").String()
  269. idInfo["idNum"], _ = j.Get("antiAddiData").Get("identity").String()
  270. strChannel, _ := j.Get("channel").Int()
  271. idInfo["chn"] = strconv.Itoa(strChannel)
  272. return idInfo
  273. }