package model import ( "encoding/base64" "encoding/json" "rocommon" "rocommon/rpc" "rocommon/service" "rocommon/util" "roserver/baseserver" "roserver/baseserver/model" "roserver/serverproto" "runtime/debug" "strings" ) var connInfoTimeOut int64 = 31 * 60 func init() { serverproto.Handle_AUTH_CSLoginReq = model.HandleBackendMessage(func(ev rocommon.ProcEvent, cliId model.ClientID) { msg := ev.Msg().(*serverproto.CSLoginReq) util.InfoF("msg Platform:%s, token:%s, openID:%s", msg.Platform, msg.PlatformToken, msg.OpenId) if !checkOpenIdValid(msg.OpenId) { LoginRet(ev, int32(serverproto.ErrorCode_ERROR_FAIL)) return } //todo... // 1,获取服务器状态,例如维护中不允许登陆 if serverStatus := checkServerStatus(); serverStatus != int32(serverproto.ErrorCode_ERROR_OK) { LoginRet(ev, int32(serverproto.ErrorCode_ERROR_FAIL)) return } sConfig := service.GetServiceConfig() whiteList := sConfig.SDKConfig.WhiteList isWhite := false if len(whiteList) > 0 { for _, white := range whiteList { if msg.OpenId == white { isWhite = true } } } else { isWhite = true } if !isWhite { LoginRet(ev, int32(serverproto.ErrorCode_ERROR_FAIL)) return } //做sdk登陆验证处理 if msg.Platform != model.SDKPlatform_PC && msg.Platform != "" { switch msg.Platform { case model.SDKPlatform_Quick: LoginVerifySign(cliId.SessID, cliId.ServiceID, msg.Platform, msg.PlatformToken, msg.OpenId) case model.SDKPlatform_Hw_Quick: LoginVerifyHwQuickSign(cliId.SessID, cliId.ServiceID, msg.Platform, msg.PlatformToken, msg.OpenId) case model.SDKPlatform_NBSDK: LoginVerifySignNBSDK(cliId.SessID, cliId.ServiceID, msg.Platform, msg.PlatformToken, msg.OpenId) case model.SDKPlatform_YouYi: fallthrough case model.SDKPlatform_YouYi_IOS: fallthrough case model.SDKPlatform_UniSDK: //对quick海外做适配 LoginVerifyHwQuickSign(cliId.SessID, cliId.ServiceID, msg.Platform, msg.PlatformToken, msg.OpenId) // //LoginVerifySignUniSDK(cliId.SessID, cliId.ServiceID, msg.Platform, msg.PlatformToken, msg.OpenId, msg.Ip) // ret := serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED // if msg.Platform == model.SDKPlatform_YouYi || msg.Platform == model.SDKPlatform_YouYi_IOS { // ret, _ = LoginVerifySignYouYiSDKJWT(msg.Platform, msg.PlatformToken, msg.OpenId) // } else if msg.Platform == model.SDKPlatform_UniSDK { // ret, _ = LoginVerifySignUniSDKJWT(msg.Platform, msg.PlatformToken, msg.OpenId) // } // if ret == serverproto.ErrorCode_ERROR_OK { // //获取用户上次登录连接信息 // var connInfo serverproto.UserConnectInfo // if !initUserConnInfo(&connInfo, msg.OpenId, msg.Platform) { // LoginRet(ev, int32(serverproto.ErrorCode_ERROR_FAIL)) // return // } // loginNtf := &serverproto.SSLoginNtf{} // loginNtf.Error = int32(serverproto.ErrorCode_ERROR_OK) // loginNtf.ClientId = cliId.SessID // loginNtf.ConnInfo = &connInfo // //if loginNtf.ConnInfo.TimeStamp+connInfoTimeOut < util.GetTimeSeconds() { // // loginNtf.ConnInfo.LogicNode = "" // // util.InfoF("connect timeout openid=%v", msg.OpenId) // //} // ev.Session().Send(loginNtf) // } else { // LoginRet(ev, int32(serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED)) // } } return //util.InfoF("need sdk check") //LoginRet(ev, int32(serverproto.ErrorCode_ERROR_FAIL)) //return } else if msg.Platform == model.SDKPlatform_PC { //获取用户上次登录连接信息 var connInfo serverproto.UserConnectInfo if !initUserConnInfo(&connInfo, msg.OpenId, "") { LoginRet(ev, int32(serverproto.ErrorCode_ERROR_FAIL)) return } loginNtf := &serverproto.SSLoginNtf{} loginNtf.Error = int32(serverproto.ErrorCode_ERROR_OK) loginNtf.ClientId = cliId.SessID loginNtf.ConnInfo = &connInfo //if loginNtf.ConnInfo.TimeStamp+connInfoTimeOut < util.GetTimeSeconds() { // loginNtf.ConnInfo.LogicNode = "" // util.InfoF("connect timeout openid=%v", msg.OpenId) //} util.InfoF("loginNtf ClientId: %v,ConnInfo: %v", loginNtf.ClientId, *loginNtf.ConnInfo) ev.Session().Send(loginNtf) } else { LoginRet(ev, int32(serverproto.ErrorCode_ERROR_ROLE_PLATFORM_EMPTY)) } }) serverproto.Handle_AUTH_SSSaveUserConnectInfo = model.HandleBackendMessage(func(ev rocommon.ProcEvent, cliId model.ClientID) { msg := ev.Msg().(*serverproto.SSSaveUserConnectInfo) saveUserConnInfo(msg.ConnInfo, msg.OpenId, msg.Platform) }) } func LoginVerifySign(clientId uint64, GateServiceNode string, platform string, token string, openId string) { authHttpAddr := "" urlPath := "" go func() { defer func() { //打印奔溃信息 if err := recover(); err != nil { util.InfoF("onError data=%v \n%s\n", err, string(debug.Stack())) } }() tmpRequest := &rocommon.HTTPRequest{} tmpRequest.ReqCodecName = "httpform" if platform == model.SDKPlatform_Quick { authHttpAddr = service.GetServiceConfig().SDKConfig.QuickHttpAddr urlPath = service.GetServiceConfig().SDKConfig.QuickHttpAuth urlPath += "?token=" + token + "&product_code=" + service.GetServiceConfig().SDKConfig.QuickProductCode urlPath += "&uid=" + openId tmpRequest.ResMsg = &SDKQuickLoginAuthCheckResp{} } parm := GetHttpNodeParam() parm.LisAddr = authHttpAddr httpNode := baseserver.CreateHttpConnector(parm) err := httpNode.(rocommon.HTTPConnector).Request("GET", urlPath, tmpRequest) tmpResMsg := tmpRequest.ResMsg tmpResMsg.(*SDKQuickLoginAuthCheckResp).ClientId = clientId tmpResMsg.(*SDKQuickLoginAuthCheckResp).ServiceId = GateServiceNode tmpResMsg.(*SDKQuickLoginAuthCheckResp).OpenId = openId tmpResMsg.(*SDKQuickLoginAuthCheckResp).Platform = platform if err != nil { tmpRequest.ResMsg.(*SDKQuickLoginAuthCheckResp).RetCode = "0" util.InfoF("uid=%v http Request openid=%v err=%v", clientId, openId, err) } GetAuthCheckMag().AddCheckList(tmpRequest.ResMsg) }() } func DoLoginQuickVerifySign(res *SDKQuickLoginAuthCheckResp) { util.InfoF("openid=%v DoLoginQuickVerifySign retCode=%v", res.OpenId, res.RetCode) gateSession := model.GetServiceNode(res.ServiceId) if gateSession == nil { return } //1验证成功,其他数据验证失败 if res.RetCode == "1" { //获取用户上次登录连接信息 var connInfo serverproto.UserConnectInfo if !initUserConnInfo(&connInfo, res.OpenId, res.Platform) { LoginRetSDK(gateSession, res.ClientId, int32(serverproto.ErrorCode_ERROR_FAIL)) return } loginNtf := &serverproto.SSLoginNtf{} loginNtf.Error = int32(serverproto.ErrorCode_ERROR_OK) loginNtf.ClientId = res.ClientId loginNtf.ConnInfo = &connInfo gateSession.Send(loginNtf) } else { LoginRetSDK(gateSession, res.ClientId, int32(serverproto.ErrorCode_ERROR_FAIL)) } } func LoginVerifySignNBSDK(clientId uint64, GateServiceNode string, platform string, token string, openId string) { authHttpAddr := "" urlPath := "" go func() { defer func() { //打印奔溃信息 if err := recover(); err != nil { util.InfoF("onError data=%v \n%s\n", err, string(debug.Stack())) } }() tmpRequest := &rocommon.HTTPRequest{} tmpRequest.ReqCodecName = "httpform" if platform == model.SDKPlatform_NBSDK { authHttpAddr = service.GetServiceConfig().SDKConfig.NbHttpAddr urlPath = service.GetServiceConfig().SDKConfig.NbHttpAuth urlPath += "?uid=" + openId + "&token=" + token tmpRequest.ResMsg = &SDKNBLoginAuthCheckResp{} } parm := GetHttpNodeParam() parm.LisAddr = authHttpAddr httpNode := baseserver.CreateHttpConnector(parm) err := httpNode.(rocommon.HTTPConnector).Request("GET", urlPath, tmpRequest) tmpResMsg := tmpRequest.ResMsg tmpResMsg.(*SDKNBLoginAuthCheckResp).ClientId = clientId tmpResMsg.(*SDKNBLoginAuthCheckResp).ServiceId = GateServiceNode tmpResMsg.(*SDKNBLoginAuthCheckResp).OpenId = openId tmpResMsg.(*SDKNBLoginAuthCheckResp).Platform = platform if err != nil { tmpRequest.ResMsg.(*SDKNBLoginAuthCheckResp).RetCode = "0" util.InfoF("uid=%v http Request openid=%v err=%v", clientId, openId, err) } GetAuthCheckMag().AddCheckList(tmpRequest.ResMsg) }() } func DoLoginNBSDKVerifySign(res *SDKNBLoginAuthCheckResp) { util.InfoF("openid=%v DoLoginNBSDKVerifySign retCode=%v", res.OpenId, res.RetCode) gateSession := model.GetServiceNode(res.ServiceId) if gateSession == nil { return } //1验证成功,其他数据验证失败 if res.RetCode == "success" || !strings.Contains(res.RetCode, "fail") { //获取用户上次登录连接信息 var connInfo serverproto.UserConnectInfo if !initUserConnInfo(&connInfo, res.OpenId, res.Platform) { LoginRetSDK(gateSession, res.ClientId, int32(serverproto.ErrorCode_ERROR_FAIL)) return } loginNtf := &serverproto.SSLoginNtf{} loginNtf.Error = int32(serverproto.ErrorCode_ERROR_OK) loginNtf.ClientId = res.ClientId loginNtf.ConnInfo = &connInfo gateSession.Send(loginNtf) } else { LoginRetSDK(gateSession, res.ClientId, int32(serverproto.ErrorCode_ERROR_FAIL)) } } var sdkUniSignAesKey = []byte("wenting123456789") func LoginVerifySignUniSDKJWT(platform, token, openId string) (serverproto.ErrorCode, string) { tokenList := strings.Split(token, ".") //userinfo.signinfo if len(tokenList) < 2 { return serverproto.ErrorCode_ERROR_FAIL, "" } if tokenList[0] == "" || tokenList[1] == "" { return serverproto.ErrorCode_ERROR_FAIL, "" } //签名匹配 userInfoData, err := base64.StdEncoding.DecodeString(tokenList[0]) if err != nil { util.InfoF("LoginVerifySignUniSDKJWT userInfoData decode failed openId=%v err=%v", openId, err) return serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED, "" } signInfoData, err := base64.StdEncoding.DecodeString(tokenList[1]) if err != nil { util.InfoF("LoginVerifySignUniSDKJWT signInfoData decode failed openId=%v err=%v", openId, err) return serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED, "" } singInfo, err := rpc.AESCtrDecrypt(signInfoData, sdkUniSignAesKey, sdkUniSignAesKey...) if err != nil { util.InfoF("LoginVerifySignUniSDKJWT sign failed openId=%v err=%v", openId, err) return serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED, "" } if string(singInfo) != string(userInfoData) { util.InfoF("LoginVerifySignUniSDKJWT sign failed openId=%v err=%v", openId, err) return serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED, "" } //openid匹配 checkUserInfo := &SDKCheckUserInfo{} err = json.Unmarshal(userInfoData, checkUserInfo) if err != nil { util.InfoF("LoginVerifySignUniSDKJWT sign failed openId=%v err=%v", openId, err) return serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED, "" } if checkUserInfo.Aid != openId { util.InfoF("LoginVerifySignUniSDKJWT openid not match openId=%v err=%v", openId, err) return serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED, "" } //过期时间处理(单位s) if checkUserInfo.ExpireTime < uint64(util.GetTimeSeconds()) { util.InfoF("LoginVerifySignUniSDKJWT expired openId=%v err=%v", openId, err) return serverproto.ErrorCode_ERROR_SDK_LOGIN_EXPIRE, "" } return serverproto.ErrorCode_ERROR_OK, checkUserInfo.AppChannel } func LoginVerifySignUniSDK(clientId uint64, GateServiceNode string, platform, token, openId, ip string) { authHttpAddr := "" urlPath := "" go func() { defer func() { //打印奔溃信息 if err := recover(); err != nil { util.InfoF("onError data=%v \n%s\n", err, string(debug.Stack())) } }() tmpRequest := &rocommon.HTTPRequest{} tmpRequest.ReqCodecName = "httpjson" authHttpAddr = service.GetServiceConfig().SDKConfig.UniHttpAddr tmpKVList := map[string]interface{}{} err := json.Unmarshal([]byte(token), &tmpKVList) if err != nil { util.InfoF("uid=%v LoginVerifySignUniSDK openid=%v err=%v", clientId, openId, err) return } tmpKVList["hostid"] = service.GetServiceConfig().Node.Zone ipStrList := strings.Split(ip, ":") if len(ipStrList) > 0 { tmpKVList["ip"] = ipStrList[0] } tmpRequest.ReqMsg = tmpKVList tmpRequest.ResMsg = &SDKUniLoginAuthCheckResp{} parm := GetHttpNodeParam() parm.LisAddr = authHttpAddr httpNode := baseserver.CreateHttpConnector(parm) err = httpNode.(rocommon.HTTPConnector).Request("POST", urlPath, tmpRequest) tmpResMsg := tmpRequest.ResMsg tmpResMsg.(*SDKUniLoginAuthCheckResp).ClientId = clientId tmpResMsg.(*SDKUniLoginAuthCheckResp).ServiceId = GateServiceNode tmpResMsg.(*SDKUniLoginAuthCheckResp).OpenId = openId tmpResMsg.(*SDKUniLoginAuthCheckResp).Platform = platform if err != nil { tmpRequest.ResMsg.(*SDKUniLoginAuthCheckResp).RetCode = "0" util.InfoF("uid=%v http Request openid=%v err=%v", clientId, openId, err) } GetAuthCheckMag().AddCheckList(tmpRequest.ResMsg) }() } func DoLoginUniSDKVerifySign(res *SDKUniLoginAuthCheckResp) { util.InfoF("openid=%v DoLoginQuickVerifySign res=%v", res.OpenId, res) gateSession := model.GetServiceNode(res.ServiceId) if gateSession == nil { return } if res.Code == 200 && res.Status == "ok" { //获取用户上次登录连接信息 var connInfo serverproto.UserConnectInfo if !initUserConnInfo(&connInfo, res.OpenId, res.Platform) { LoginRetSDK(gateSession, res.ClientId, int32(serverproto.ErrorCode_ERROR_FAIL)) return } loginNtf := &serverproto.SSLoginNtf{} loginNtf.Error = int32(serverproto.ErrorCode_ERROR_OK) loginNtf.ClientId = res.ClientId loginNtf.ConnInfo = &connInfo loginNtf.SdkParam = res.UniSDKLoginJson gateSession.Send(loginNtf) } else { LoginRetSDK(gateSession, res.ClientId, int32(serverproto.ErrorCode_ERROR_FAIL)) } } func LoginVerifySignYouYiSDKJWT(platform, token, openId string) (serverproto.ErrorCode, string) { tokenList := strings.Split(token, ".") //userinfo.signinfo if len(tokenList) < 2 { return serverproto.ErrorCode_ERROR_FAIL, "" } if tokenList[0] == "" || tokenList[1] == "" { return serverproto.ErrorCode_ERROR_FAIL, "" } //签名匹配 userInfoData, err := base64.StdEncoding.DecodeString(tokenList[0]) if err != nil { util.InfoF("LoginVerifySignUniSDKJWT userInfoData decode failed openId=%v err=%v", openId, err) return serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED, "" } signInfoData, err := base64.StdEncoding.DecodeString(tokenList[1]) if err != nil { util.InfoF("LoginVerifySignUniSDKJWT signInfoData decode failed openId=%v err=%v", openId, err) return serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED, "" } singInfo, err := rpc.AESCtrDecrypt(signInfoData, sdkUniSignAesKey, sdkUniSignAesKey...) if err != nil { util.InfoF("LoginVerifySignUniSDKJWT sign failed openId=%v err=%v", openId, err) return serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED, "" } if string(singInfo) != string(userInfoData) { util.InfoF("LoginVerifySignUniSDKJWT sign failed openId=%v err=%v", openId, err) return serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED, "" } //openid匹配 checkUserInfo := &SDKCheckUserInfo{} err = json.Unmarshal(userInfoData, checkUserInfo) if err != nil { util.InfoF("LoginVerifySignUniSDKJWT sign failed openId=%v err=%v", openId, err) return serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED, "" } if checkUserInfo.Aid != openId { util.InfoF("LoginVerifySignUniSDKJWT openid not match openId=%v err=%v", openId, err) return serverproto.ErrorCode_ERROR_SDK_LOGIN_FAILED, "" } ////过期时间处理(单位s) //if checkUserInfo.ExpireTime < uint64(util.GetTimeSeconds()) { // util.InfoF("LoginVerifySignUniSDKJWT expired openId=%v err=%v", openId, err) // return serverproto.ErrorCode_ERROR_SDK_LOGIN_EXPIRE, "" //} return serverproto.ErrorCode_ERROR_OK, checkUserInfo.AppChannel } // 海外quick func LoginVerifyHwQuickSign(clientId uint64, GateServiceNode string, platform string, token string, openId string) { authHttpAddr := "" urlPath := "" go func() { defer func() { //打印奔溃信息 if err := recover(); err != nil { util.InfoF("onError data=%v \n%s\n", err, string(debug.Stack())) } }() tmpRequest := &rocommon.HTTPRequest{} tmpRequest.ReqCodecName = "httpjson" //为海外quick做适配 // if platform == model.SDKPlatform_Hw_Quick { if true { authHttpAddr = "http://pxqg.hkhappygame.com" urlPath = "/webapi/checkUserInfo?token=" + token + "&uid=" + openId tmpRequest.ResMsg = &SDKHwQuickLoginAuthCheckResp{} util.InfoF("urlPath=%v", urlPath) } parm := GetHttpNodeParam() parm.LisAddr = authHttpAddr httpNode := baseserver.CreateHttpConnector(parm) err := httpNode.(rocommon.HTTPConnector).Request("GET", urlPath, tmpRequest) tmpResMsg := tmpRequest.ResMsg util.InfoF("tmpRequest.ResMsg:%v", tmpRequest.ResMsg) tmpResMsg.(*SDKHwQuickLoginAuthCheckResp).ClientId = clientId tmpResMsg.(*SDKHwQuickLoginAuthCheckResp).ServiceId = GateServiceNode tmpResMsg.(*SDKHwQuickLoginAuthCheckResp).OpenId = openId tmpResMsg.(*SDKHwQuickLoginAuthCheckResp).Platform = platform if err != nil { tmpRequest.ResMsg.(*SDKHwQuickLoginAuthCheckResp).Status = false util.InfoF("uid=%v http Request openid=%v err=%v", clientId, openId, err) } GetAuthCheckMag().AddCheckList(tmpRequest.ResMsg) }() } // SDKUniLoginAuthCheckResp func DoLoginHwQuickVerifySign(res *SDKHwQuickLoginAuthCheckResp) { util.InfoF("openid=%v DoLoginHWQuickVerifySign retCode=%v", res.OpenId, res.RetCode) gateSession := model.GetServiceNode(res.ServiceId) if gateSession == nil { return } //1验证成功,其他数据验证失败 if res.Status { util.InfoF("验证通过") //获取用户上次登录连接信息 var connInfo serverproto.UserConnectInfo if !initUserConnInfo(&connInfo, res.OpenId, res.Platform) { LoginRetSDK(gateSession, res.ClientId, int32(serverproto.ErrorCode_ERROR_FAIL)) return } loginNtf := &serverproto.SSLoginNtf{} loginNtf.Error = int32(serverproto.ErrorCode_ERROR_OK) loginNtf.ClientId = res.ClientId loginNtf.ConnInfo = &connInfo gateSession.Send(loginNtf) } else { LoginRetSDK(gateSession, res.ClientId, int32(serverproto.ErrorCode_ERROR_FAIL)) } }