auth_msg.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. package model
  2. import (
  3. "encoding/base64"
  4. "encoding/json"
  5. "rocommon"
  6. "rocommon/rpc"
  7. "rocommon/service"
  8. "rocommon/util"
  9. "roserver/baseserver"
  10. "roserver/baseserver/model"
  11. "roserver/serverproto"
  12. "runtime/debug"
  13. "strings"
  14. )
  15. var connInfoTimeOut int64 = 31 * 60
  16. func init() {
  17. serverproto.Handle_AUTH_CSLoginReq = model.HandleBackendMessage(func(ev rocommon.ProcEvent, cliId model.ClientID) {
  18. msg := ev.Msg().(*serverproto.CSLoginReq)
  19. if !checkOpenIdValid(msg.OpenId) {
  20. LoginRet(ev, int32(serverproto.ErrorCode_ERROR_FAIL))
  21. return
  22. }
  23. //todo...
  24. // 1,获取服务器状态,例如维护中不允许登陆
  25. if serverStatus := checkServerStatus(); serverStatus != int32(serverproto.ErrorCode_ERROR_OK) {
  26. LoginRet(ev, int32(serverproto.ErrorCode_ERROR_FAIL))
  27. return
  28. }
  29. //做sdk登陆验证处理
  30. if msg.Platform != model.SDKPlatform_PC && msg.Platform != "" {
  31. switch msg.Platform {
  32. case model.SDKPlatform_Quick:
  33. LoginVerifySign(cliId.SessID, cliId.ServiceID, msg.Platform, msg.PlatformToken, msg.OpenId)
  34. case model.SDKPlatform_NBSDK:
  35. LoginVerifySignNBSDK(cliId.SessID, cliId.ServiceID, msg.Platform, msg.PlatformToken, msg.OpenId)
  36. case model.SDKPlatform_YouYi:
  37. fallthrough
  38. case model.SDKPlatform_YouYi_IOS:
  39. fallthrough
  40. case model.SDKPlatform_BTSuper:
  41. fallthrough
  42. case model.SDKPlatform_UniSDK:
  43. //LoginVerifySignUniSDK(cliId.SessID, cliId.ServiceID, msg.Platform, msg.PlatformToken, msg.OpenId, msg.Ip)
  44. ret := serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED
  45. if msg.Platform == model.SDKPlatform_YouYi || msg.Platform == model.SDKPlatform_YouYi_IOS ||
  46. msg.Platform == model.SDKPlatform_BTSuper {
  47. ret, _ = LoginVerifySignYouYiSDKJWT(msg.Platform, msg.PlatformToken, msg.OpenId)
  48. } else if msg.Platform == model.SDKPlatform_UniSDK {
  49. ret, _ = LoginVerifySignUniSDKJWT(msg.Platform, msg.PlatformToken, msg.OpenId)
  50. }
  51. if ret == serverproto.ErrorCode_ERROR_OK {
  52. //获取用户上次登录连接信息
  53. var connInfo serverproto.UserConnectInfo
  54. if !initUserConnInfo(&connInfo, msg.OpenId, msg.Platform) {
  55. LoginRet(ev, int32(serverproto.ErrorCode_ERROR_FAIL))
  56. return
  57. }
  58. loginNtf := &serverproto.SSLoginNtf{}
  59. loginNtf.Error = int32(serverproto.ErrorCode_ERROR_OK)
  60. loginNtf.ClientId = cliId.SessID
  61. loginNtf.ConnInfo = &connInfo
  62. //if loginNtf.ConnInfo.TimeStamp+connInfoTimeOut < util.GetTimeSeconds() {
  63. // loginNtf.ConnInfo.LogicNode = ""
  64. // util.InfoF("connect timeout openid=%v", msg.OpenId)
  65. //}
  66. ev.Session().Send(loginNtf)
  67. } else {
  68. LoginRet(ev, int32(serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED))
  69. }
  70. }
  71. return
  72. //util.InfoF("need sdk check")
  73. //LoginRet(ev, int32(serverproto.ErrorCode_ERROR_FAIL))
  74. //return
  75. } else if msg.Platform == model.SDKPlatform_PC {
  76. //获取用户上次登录连接信息
  77. var connInfo serverproto.UserConnectInfo
  78. if !initUserConnInfo(&connInfo, msg.OpenId, "") {
  79. LoginRet(ev, int32(serverproto.ErrorCode_ERROR_FAIL))
  80. return
  81. }
  82. loginNtf := &serverproto.SSLoginNtf{}
  83. loginNtf.Error = int32(serverproto.ErrorCode_ERROR_OK)
  84. loginNtf.ClientId = cliId.SessID
  85. loginNtf.ConnInfo = &connInfo
  86. //if loginNtf.ConnInfo.TimeStamp+connInfoTimeOut < util.GetTimeSeconds() {
  87. // loginNtf.ConnInfo.LogicNode = ""
  88. // util.InfoF("connect timeout openid=%v", msg.OpenId)
  89. //}
  90. ev.Session().Send(loginNtf)
  91. } else {
  92. LoginRet(ev, int32(serverproto.ErrorCode_ERROR_ROLE_PLATFORM_EMPTY))
  93. }
  94. })
  95. serverproto.Handle_AUTH_SSSaveUserConnectInfo = model.HandleBackendMessage(func(ev rocommon.ProcEvent, cliId model.ClientID) {
  96. msg := ev.Msg().(*serverproto.SSSaveUserConnectInfo)
  97. saveUserConnInfo(msg.ConnInfo, msg.OpenId, msg.Platform)
  98. })
  99. }
  100. func LoginVerifySign(clientId uint64, GateServiceNode string, platform string, token string, openId string) {
  101. authHttpAddr := ""
  102. urlPath := ""
  103. go func() {
  104. defer func() {
  105. //打印奔溃信息
  106. if err := recover(); err != nil {
  107. util.InfoF("onError data=%v \n%s\n", err, string(debug.Stack()))
  108. }
  109. }()
  110. tmpRequest := &rocommon.HTTPRequest{}
  111. tmpRequest.ReqCodecName = "httpform"
  112. if platform == model.SDKPlatform_Quick {
  113. authHttpAddr = service.GetServiceConfig().SDKConfig.QuickHttpAddr
  114. urlPath = service.GetServiceConfig().SDKConfig.QuickHttpAuth
  115. urlPath += "?token=" + token + "&product_code=" + service.GetServiceConfig().SDKConfig.QuickProductCode
  116. urlPath += "&uid=" + openId
  117. tmpRequest.ResMsg = &SDKQuickLoginAuthCheckResp{}
  118. }
  119. parm := GetHttpNodeParam()
  120. parm.LisAddr = authHttpAddr
  121. httpNode := baseserver.CreateHttpConnector(parm)
  122. err := httpNode.(rocommon.HTTPConnector).Request("GET", urlPath, tmpRequest)
  123. tmpResMsg := tmpRequest.ResMsg
  124. tmpResMsg.(*SDKQuickLoginAuthCheckResp).ClientId = clientId
  125. tmpResMsg.(*SDKQuickLoginAuthCheckResp).ServiceId = GateServiceNode
  126. tmpResMsg.(*SDKQuickLoginAuthCheckResp).OpenId = openId
  127. tmpResMsg.(*SDKQuickLoginAuthCheckResp).Platform = platform
  128. if err != nil {
  129. tmpRequest.ResMsg.(*SDKQuickLoginAuthCheckResp).RetCode = "0"
  130. util.InfoF("uid=%v http Request openid=%v err=%v", clientId, openId, err)
  131. }
  132. GetAuthCheckMag().AddCheckList(tmpRequest.ResMsg)
  133. }()
  134. }
  135. func DoLoginQuickVerifySign(res *SDKQuickLoginAuthCheckResp) {
  136. util.InfoF("openid=%v DoLoginQuickVerifySign retCode=%v", res.OpenId, res.RetCode)
  137. gateSession := model.GetServiceNode(res.ServiceId)
  138. if gateSession == nil {
  139. return
  140. }
  141. //1验证成功,其他数据验证失败
  142. if res.RetCode == "1" {
  143. //获取用户上次登录连接信息
  144. var connInfo serverproto.UserConnectInfo
  145. if !initUserConnInfo(&connInfo, res.OpenId, res.Platform) {
  146. LoginRetSDK(gateSession, res.ClientId, int32(serverproto.ErrorCode_ERROR_FAIL))
  147. return
  148. }
  149. loginNtf := &serverproto.SSLoginNtf{}
  150. loginNtf.Error = int32(serverproto.ErrorCode_ERROR_OK)
  151. loginNtf.ClientId = res.ClientId
  152. loginNtf.ConnInfo = &connInfo
  153. gateSession.Send(loginNtf)
  154. } else {
  155. LoginRetSDK(gateSession, res.ClientId, int32(serverproto.ErrorCode_ERROR_FAIL))
  156. }
  157. }
  158. func LoginVerifySignNBSDK(clientId uint64, GateServiceNode string, platform string, token string, openId string) {
  159. authHttpAddr := ""
  160. urlPath := ""
  161. go func() {
  162. defer func() {
  163. //打印奔溃信息
  164. if err := recover(); err != nil {
  165. util.InfoF("onError data=%v \n%s\n", err, string(debug.Stack()))
  166. }
  167. }()
  168. tmpRequest := &rocommon.HTTPRequest{}
  169. tmpRequest.ReqCodecName = "httpform"
  170. if platform == model.SDKPlatform_NBSDK {
  171. authHttpAddr = service.GetServiceConfig().SDKConfig.NbHttpAddr
  172. urlPath = service.GetServiceConfig().SDKConfig.NbHttpAuth
  173. urlPath += "?uid=" + openId + "&token=" + token
  174. tmpRequest.ResMsg = &SDKNBLoginAuthCheckResp{}
  175. }
  176. parm := GetHttpNodeParam()
  177. parm.LisAddr = authHttpAddr
  178. httpNode := baseserver.CreateHttpConnector(parm)
  179. err := httpNode.(rocommon.HTTPConnector).Request("GET", urlPath, tmpRequest)
  180. tmpResMsg := tmpRequest.ResMsg
  181. tmpResMsg.(*SDKNBLoginAuthCheckResp).ClientId = clientId
  182. tmpResMsg.(*SDKNBLoginAuthCheckResp).ServiceId = GateServiceNode
  183. tmpResMsg.(*SDKNBLoginAuthCheckResp).OpenId = openId
  184. tmpResMsg.(*SDKNBLoginAuthCheckResp).Platform = platform
  185. if err != nil {
  186. tmpRequest.ResMsg.(*SDKNBLoginAuthCheckResp).RetCode = "0"
  187. util.InfoF("uid=%v http Request openid=%v err=%v", clientId, openId, err)
  188. }
  189. GetAuthCheckMag().AddCheckList(tmpRequest.ResMsg)
  190. }()
  191. }
  192. func DoLoginNBSDKVerifySign(res *SDKNBLoginAuthCheckResp) {
  193. util.InfoF("openid=%v DoLoginNBSDKVerifySign retCode=%v", res.OpenId, res.RetCode)
  194. gateSession := model.GetServiceNode(res.ServiceId)
  195. if gateSession == nil {
  196. return
  197. }
  198. //1验证成功,其他数据验证失败
  199. if res.RetCode == "success" || !strings.Contains(res.RetCode, "fail") {
  200. //获取用户上次登录连接信息
  201. var connInfo serverproto.UserConnectInfo
  202. if !initUserConnInfo(&connInfo, res.OpenId, res.Platform) {
  203. LoginRetSDK(gateSession, res.ClientId, int32(serverproto.ErrorCode_ERROR_FAIL))
  204. return
  205. }
  206. loginNtf := &serverproto.SSLoginNtf{}
  207. loginNtf.Error = int32(serverproto.ErrorCode_ERROR_OK)
  208. loginNtf.ClientId = res.ClientId
  209. loginNtf.ConnInfo = &connInfo
  210. gateSession.Send(loginNtf)
  211. } else {
  212. LoginRetSDK(gateSession, res.ClientId, int32(serverproto.ErrorCode_ERROR_FAIL))
  213. }
  214. }
  215. var sdkUniSignAesKey = []byte("wenting123456789")
  216. func LoginVerifySignUniSDKJWT(platform, token, openId string) (serverproto.ErrorCode, string) {
  217. tokenList := strings.Split(token, ".") //userinfo.signinfo
  218. if len(tokenList) < 2 {
  219. return serverproto.ErrorCode_ERROR_FAIL, ""
  220. }
  221. if tokenList[0] == "" || tokenList[1] == "" {
  222. return serverproto.ErrorCode_ERROR_FAIL, ""
  223. }
  224. //签名匹配
  225. userInfoData, err := base64.StdEncoding.DecodeString(tokenList[0])
  226. if err != nil {
  227. util.InfoF("LoginVerifySignUniSDKJWT userInfoData decode failed openId=%v err=%v", openId, err)
  228. return serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED, ""
  229. }
  230. signInfoData, err := base64.StdEncoding.DecodeString(tokenList[1])
  231. if err != nil {
  232. util.InfoF("LoginVerifySignUniSDKJWT signInfoData decode failed openId=%v err=%v", openId, err)
  233. return serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED, ""
  234. }
  235. singInfo, err := rpc.AESCtrDecrypt(signInfoData, sdkUniSignAesKey, sdkUniSignAesKey...)
  236. if err != nil {
  237. util.InfoF("LoginVerifySignUniSDKJWT sign failed openId=%v err=%v", openId, err)
  238. return serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED, ""
  239. }
  240. if string(singInfo) != string(userInfoData) {
  241. util.InfoF("LoginVerifySignUniSDKJWT sign failed openId=%v err=%v", openId, err)
  242. return serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED, ""
  243. }
  244. //openid匹配
  245. checkUserInfo := &SDKCheckUserInfo{}
  246. err = json.Unmarshal(userInfoData, checkUserInfo)
  247. if err != nil {
  248. util.InfoF("LoginVerifySignUniSDKJWT sign failed openId=%v err=%v", openId, err)
  249. return serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED, ""
  250. }
  251. if checkUserInfo.Aid != openId {
  252. util.InfoF("LoginVerifySignUniSDKJWT openid not match openId=%v err=%v", openId, err)
  253. return serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED, ""
  254. }
  255. //过期时间处理(单位s)
  256. if checkUserInfo.ExpireTime < uint64(util.GetTimeSeconds()) {
  257. util.InfoF("LoginVerifySignUniSDKJWT expired openId=%v err=%v", openId, err)
  258. return serverproto.ErrorCode_ERROR_SDK_LOGIN_EXPIRE, ""
  259. }
  260. return serverproto.ErrorCode_ERROR_OK, checkUserInfo.AppChannel
  261. }
  262. func LoginVerifySignUniSDK(clientId uint64, GateServiceNode string, platform, token, openId, ip string) {
  263. authHttpAddr := ""
  264. urlPath := ""
  265. go func() {
  266. defer func() {
  267. //打印奔溃信息
  268. if err := recover(); err != nil {
  269. util.InfoF("onError data=%v \n%s\n", err, string(debug.Stack()))
  270. }
  271. }()
  272. tmpRequest := &rocommon.HTTPRequest{}
  273. tmpRequest.ReqCodecName = "httpjson"
  274. authHttpAddr = service.GetServiceConfig().SDKConfig.UniHttpAddr
  275. tmpKVList := map[string]interface{}{}
  276. err := json.Unmarshal([]byte(token), &tmpKVList)
  277. if err != nil {
  278. util.InfoF("uid=%v LoginVerifySignUniSDK openid=%v err=%v", clientId, openId, err)
  279. return
  280. }
  281. tmpKVList["hostid"] = service.GetServiceConfig().Node.Zone
  282. ipStrList := strings.Split(ip, ":")
  283. if len(ipStrList) > 0 {
  284. tmpKVList["ip"] = ipStrList[0]
  285. }
  286. tmpRequest.ReqMsg = tmpKVList
  287. tmpRequest.ResMsg = &SDKUniLoginAuthCheckResp{}
  288. parm := GetHttpNodeParam()
  289. parm.LisAddr = authHttpAddr
  290. httpNode := baseserver.CreateHttpConnector(parm)
  291. err = httpNode.(rocommon.HTTPConnector).Request("POST", urlPath, tmpRequest)
  292. tmpResMsg := tmpRequest.ResMsg
  293. tmpResMsg.(*SDKUniLoginAuthCheckResp).ClientId = clientId
  294. tmpResMsg.(*SDKUniLoginAuthCheckResp).ServiceId = GateServiceNode
  295. tmpResMsg.(*SDKUniLoginAuthCheckResp).OpenId = openId
  296. tmpResMsg.(*SDKUniLoginAuthCheckResp).Platform = platform
  297. if err != nil {
  298. tmpRequest.ResMsg.(*SDKUniLoginAuthCheckResp).RetCode = "0"
  299. util.InfoF("uid=%v http Request openid=%v err=%v", clientId, openId, err)
  300. }
  301. GetAuthCheckMag().AddCheckList(tmpRequest.ResMsg)
  302. }()
  303. }
  304. func DoLoginUniSDKVerifySign(res *SDKUniLoginAuthCheckResp) {
  305. util.InfoF("openid=%v DoLoginQuickVerifySign res=%v", res.OpenId, res)
  306. gateSession := model.GetServiceNode(res.ServiceId)
  307. if gateSession == nil {
  308. return
  309. }
  310. if res.Code == 200 && res.Status == "ok" {
  311. //获取用户上次登录连接信息
  312. var connInfo serverproto.UserConnectInfo
  313. if !initUserConnInfo(&connInfo, res.OpenId, res.Platform) {
  314. LoginRetSDK(gateSession, res.ClientId, int32(serverproto.ErrorCode_ERROR_FAIL))
  315. return
  316. }
  317. loginNtf := &serverproto.SSLoginNtf{}
  318. loginNtf.Error = int32(serverproto.ErrorCode_ERROR_OK)
  319. loginNtf.ClientId = res.ClientId
  320. loginNtf.ConnInfo = &connInfo
  321. loginNtf.SdkParam = res.UniSDKLoginJson
  322. gateSession.Send(loginNtf)
  323. } else {
  324. LoginRetSDK(gateSession, res.ClientId, int32(serverproto.ErrorCode_ERROR_FAIL))
  325. }
  326. }
  327. func LoginVerifySignYouYiSDKJWT(platform, token, openId string) (serverproto.ErrorCode, string) {
  328. tokenList := strings.Split(token, ".") //userinfo.signinfo
  329. if len(tokenList) < 2 {
  330. return serverproto.ErrorCode_ERROR_FAIL, ""
  331. }
  332. if tokenList[0] == "" || tokenList[1] == "" {
  333. return serverproto.ErrorCode_ERROR_FAIL, ""
  334. }
  335. //签名匹配
  336. userInfoData, err := base64.StdEncoding.DecodeString(tokenList[0])
  337. if err != nil {
  338. util.InfoF("LoginVerifySignUniSDKJWT userInfoData decode failed openId=%v err=%v", openId, err)
  339. return serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED, ""
  340. }
  341. signInfoData, err := base64.StdEncoding.DecodeString(tokenList[1])
  342. if err != nil {
  343. util.InfoF("LoginVerifySignUniSDKJWT signInfoData decode failed openId=%v err=%v", openId, err)
  344. return serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED, ""
  345. }
  346. singInfo, err := rpc.AESCtrDecrypt(signInfoData, sdkUniSignAesKey, sdkUniSignAesKey...)
  347. if err != nil {
  348. util.InfoF("LoginVerifySignUniSDKJWT sign failed openId=%v err=%v", openId, err)
  349. return serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED, ""
  350. }
  351. if string(singInfo) != string(userInfoData) {
  352. util.InfoF("LoginVerifySignUniSDKJWT sign failed openId=%v err=%v", openId, err)
  353. return serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED, ""
  354. }
  355. //openid匹配
  356. checkUserInfo := &SDKCheckUserInfo{}
  357. err = json.Unmarshal(userInfoData, checkUserInfo)
  358. if err != nil {
  359. util.InfoF("LoginVerifySignUniSDKJWT sign failed openId=%v err=%v", openId, err)
  360. return serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED, ""
  361. }
  362. if checkUserInfo.Aid != openId {
  363. util.InfoF("LoginVerifySignUniSDKJWT openid not match openId=%v err=%v", openId, err)
  364. return serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED, ""
  365. }
  366. ////过期时间处理(单位s)
  367. //if checkUserInfo.ExpireTime < uint64(util.GetTimeSeconds()) {
  368. // util.InfoF("LoginVerifySignUniSDKJWT expired openId=%v err=%v", openId, err)
  369. // return serverproto.ErrorCode_ERROR_SDK_LOGIN_EXPIRE, ""
  370. //}
  371. return serverproto.ErrorCode_ERROR_OK, checkUserInfo.AppChannel
  372. }