diff --git a/src/HttpServer/logic/constdef.go b/src/HttpServer/logic/constdef.go index d695f8e..a4096a8 100644 --- a/src/HttpServer/logic/constdef.go +++ b/src/HttpServer/logic/constdef.go @@ -1,5 +1,9 @@ package logic +var ( + WETCHATAPPID="wx572a2a5ec4538f33" + WETCHATSERCRT = "b31e2e7406af88fe7395cd178bdb64fc" +) const ( FRIEND_MAX_NUM = 50 //好友人数上限 diff --git a/src/HttpServer/logic/datadef.go b/src/HttpServer/logic/datadef.go index 2c09ab0..7498f42 100644 --- a/src/HttpServer/logic/datadef.go +++ b/src/HttpServer/logic/datadef.go @@ -14,6 +14,20 @@ const ( ) +type WechatLoginReq struct { + Channel_id int `json:"channel_id"` + Invite_type int `json:"invite_type"` + Invite_res_id int `json:"invite_res_id"` + User_invite_uid int `json:"user_invite_uid"` + Code string `json:"code"` + Signature string `json:"signature"` + Iv string `json:"iv"` + Raw_data string `json:"raw_data"` + Encrypted_data string `json:"encrypted_data"` + Token string `json:"token"` + Version string `json:"version"` +} + type UserLoginReq struct { Channel_id int `json:"channel_id"` Invite_type int `json:"invite_type"` @@ -23,9 +37,6 @@ type UserLoginReq struct { RefAppId int `json:"refAppId"` Code string `json:"code"` Token string `json:"token"` - Logintype int `json:"logintype"` - Useraccount string `json:"useraccount"` - Userpwd string `json:"userpwd"` Version string `json:"version"` } diff --git a/src/HttpServer/logic/errordef.go b/src/HttpServer/logic/errordef.go index 1add74f..9b66efc 100644 --- a/src/HttpServer/logic/errordef.go +++ b/src/HttpServer/logic/errordef.go @@ -35,4 +35,5 @@ const ( ERROR_FRIENDNOTFRIEND = 30 //不是好友 ERROR_FRIENDDELFRIENDFAILED = 31 //删除好友失败 ERROR_FRIENDGETFRIENDINFOFAILED = 32 //获取好友信息失败 + ERROR_WECHATLOGINFAILED = 33 //获取好友信息失败 ) \ No newline at end of file diff --git a/src/HttpServer/logic/httpserver.go b/src/HttpServer/logic/httpserver.go index fd39106..7383531 100644 --- a/src/HttpServer/logic/httpserver.go +++ b/src/HttpServer/logic/httpserver.go @@ -29,7 +29,8 @@ func CheckErr(err error) { } func startServerHttpServe() { - http.HandleFunc("/catcafe/login", UserLogin) //登录 + http.HandleFunc("/catcafe/login", UserLogin) //游客登录 + http.HandleFunc("/catcafe/wechatlogin", Wechatlogin) //微信登录 http.HandleFunc("/catcafe/user/saveUserData", SaveUserData) //保存用户数据 http.HandleFunc("/catcafe/data/saveData", SaveData) //保存游戏自定义数据 http.HandleFunc("/catcafe/data/getData", GetData) //获取自定义数据 @@ -60,6 +61,18 @@ func startServerHttpServe() { } +func Wechatlogin(w http.ResponseWriter, r *http.Request) { + + result, _ := ioutil.ReadAll(r.Body) + r.Body.Close() + + s := string(result) + logger.Info("Wechatlogin , body:%v,uuid=%v", s) + + HandleWechatlogin(w,s) +} + + func QueryPlayerData(w http.ResponseWriter, r *http.Request) { result, _ := ioutil.ReadAll(r.Body) diff --git a/src/HttpServer/logic/logic.go b/src/HttpServer/logic/logic.go index a1d82b2..d278077 100644 --- a/src/HttpServer/logic/logic.go +++ b/src/HttpServer/logic/logic.go @@ -25,6 +25,44 @@ func init() { } +func InitUserExt(req *UserLoginReq,resp *UserLoginResp,uuid int) { + var extdata UserExtData + extdata.User_id = uuid + extdata.Lv = 1 + extdata.Bean = 0 + extdata.Coin = 0 + extdata.Exp = 0 + extdata.Hot = 0 + extdata.Invite_uid = req.User_invite_uid + extdata.LoveExp = 0 + extdata.Reg_time = int(time.Now().Unix()) + extdata.ShopNum = 0 + extdata.User_channel = req.Channel_id + extdata.User_is_black = 0 + extdata.User_reg_time = int(time.Now().Unix()) + extdata.User_scene = req.Scene + resp.Result.Data.Extdata = extdata + //保存 + udata :=new(UserData) + udata.Scene = extdata.User_scene + udata.Hot = extdata.Hot + udata.Exp = extdata.Exp + udata.Coin = extdata.Coin + udata.Bean = extdata.Bean + udata.Lv = extdata.Lv + udata.Channel = extdata.User_channel + udata.InviteUid = extdata.Invite_uid + udata.Isblack = extdata.User_is_black + udata.Loevexp = extdata.LoveExp + udata.Regtime = extdata.Reg_time + udata.Shopnum = extdata.ShopNum + udata.Userid = extdata.User_id + udata.UserInviteId = extdata.User_invite_uid + udata.Userregtime = extdata.User_reg_time + + SaveUserExt(udata) +} + func InitTourist(req *UserLoginReq,resp *UserLoginResp) { //首先生成user_base_data @@ -43,6 +81,28 @@ func InitTourist(req *UserLoginReq,resp *UserLoginResp) { SetTouristUid(req.Token,basedata.User_id) //然后生成user_ext_data + InitUserExt(req,resp,basedata.User_id) + +} + +//微信登录账户初始化 +func InitWeChatUser(req *WechatLoginReq,resp *UserLoginResp,uinfo *WxUserInfo) { + //首先生成user_base_data + var basedata UserBaseData + basedata.User_id = GetNewUUid() + basedata.User_avatar_url = uinfo.AvatarURL + basedata.User_city = uinfo.City + basedata.User_gender = uinfo.Gender + basedata.User_nickname = uinfo.NickName + basedata.User_openid = uinfo.OpenID + basedata.User_token = req.Token + resp.Result.Data.Dasedata = basedata + //保存base data + basic, _ := json.Marshal(&basedata) + SaveUserBasic(basedata.User_id,string(basic)) + + SetTouristUid(uinfo.OpenID,basedata.User_id) + //然后生成user_ext_data var extdata UserExtData extdata.User_id = basedata.User_id extdata.Lv = 1 @@ -57,7 +117,7 @@ func InitTourist(req *UserLoginReq,resp *UserLoginResp) { extdata.User_channel = req.Channel_id extdata.User_is_black = 0 extdata.User_reg_time = int(time.Now().Unix()) - extdata.User_scene = req.Scene + extdata.User_scene = 0 resp.Result.Data.Extdata = extdata //保存 udata :=new(UserData) @@ -81,6 +141,65 @@ func InitTourist(req *UserLoginReq,resp *UserLoginResp) { } +//处理微信登录 +func HandleWechatlogin(w http.ResponseWriter, data string) { + + SetHeader(w) + var resp UserLoginResp + resp.Status = "true" + resp.Result.Code = ERROR_OK + var rdata WechatLoginReq + err := json.Unmarshal([]byte(data), &rdata) + for { + if err != nil { + logger.Error("HandleWechatlogin json unmarshal failed=%v", err) + resp.Result.Code = ERROR_JSONUNMASHFAILED + break + } + + pc := NewWXUserDataCrypt(WETCHATAPPID, WETCHATSERCRT) + userInfo, err := pc.Decrypt(rdata.Encrypted_data, rdata.Iv) + if err != nil { + logger.Error("HandleWechatlogin wechatloginfailed failed=%v", err) + resp.Result.Code = ERROR_WECHATLOGINFAILED + break + } + logger.Info("HandleWechatlogin userInfo=%v",userInfo) + + uuid,_ := GetTouristUid(userInfo.OpenID) + if uuid == 0 { + //新的账号 需要初始化保存 + InitWeChatUser(&rdata,&resp,userInfo) + }else { + //读取数据 + basic,err := GetUserBasic(uuid) + if err != nil { + logger.Error("HandleWechatlogin getbasic failed=%v", err) + resp.Result.Code = ERROR_GETUSERBASICFAILED + break + } + resp.Result.Data.Dasedata = *basic + + ext,err := GetUserExt(uuid) + if err != nil { + logger.Error("HandleWechatlogin getext failed=%v", err) + resp.Result.Code = ERROR_GETUSEREXTFAILED + break + } + resp.Result.Data.Extdata = *ext + + m_userInfo.Set(uint32(ext.User_id),ext) + } + + resp.Result.Code = ERROR_OK + break + } + + //回包 + respstr, _ := json.Marshal(&resp) + fmt.Fprint(w, string(respstr)) +} + //处理游客登录 func HandleTouristLogin(w http.ResponseWriter, req *UserLoginReq,resp *UserLoginResp) { @@ -134,23 +253,11 @@ func HandleUserLogin(w http.ResponseWriter, data string) { break } - if rdata.Logintype ==LOGIN_TYPE_TOURIST { - //游客登录 - HandleTouristLogin(w,&rdata,&resp) - break - } - if rdata.Logintype == LOGIN_TYPE_ACCOUNT { - //账号密码登录 + HandleTouristLogin(w,&rdata,&resp) - break - } - if rdata.Logintype == LOGIN_TYPE_WECHAT { - //微信登录 - break - } } @@ -301,7 +408,7 @@ func HandlegetData(w http.ResponseWriter, data string) { } func GetAccessToken() string{ - //首先从缓存取 + //首先从缓存取kwiffwiffiaowosfwkfko exist,err := redishandler.GetRedisClient().Exists(redis.MSG_CKECK_ACCESSTOKEN) if err != nil { logger.Error("GetAccessToken err=%v",err) diff --git a/src/HttpServer/logic/wechat.go b/src/HttpServer/logic/wechat.go new file mode 100644 index 0000000..462da4a --- /dev/null +++ b/src/HttpServer/logic/wechat.go @@ -0,0 +1,98 @@ +package logic + +import ( + "crypto/aes" + "crypto/cipher" + "encoding/base64" + "encoding/json" + "errors" +) + +var ( + ErrAppIDNotMatch = errors.New("app id not match") + ErrInvalidBlockSize = errors.New("invalid block size") + ErrInvalidPKCS7Data = errors.New("invalid PKCS7 data") + ErrInvalidPKCS7Padding = errors.New("invalid padding on input") +) + +type WxUserInfo struct { + OpenID string `json:"openId"` + UnionID string `json:"unionId"` + NickName string `json:"nickName"` + Gender int `json:"gender"` + City string `json:"city"` + Province string `json:"province"` + Country string `json:"country"` + AvatarURL string `json:"avatarUrl"` + Language string `json:"language"` + Watermark struct { + Timestamp int64 `json:"timestamp"` + AppID string `json:"appid"` + } `json:"watermark"` +} + +type WXUserDataCrypt struct { + appID, sessionKey string +} + +func NewWXUserDataCrypt(appID, sessionKey string) *WXUserDataCrypt { + return &WXUserDataCrypt{ + appID: appID, + sessionKey: sessionKey, + } +} + +// pkcs7Unpad returns slice of the original data without padding +func pkcs7Unpad(data []byte, blockSize int) ([]byte, error) { + if blockSize <= 0 { + return nil, ErrInvalidBlockSize + } + if len(data)%blockSize != 0 || len(data) == 0 { + return nil, ErrInvalidPKCS7Data + } + c := data[len(data)-1] + n := int(c) + if n == 0 || n > len(data) { + return nil, ErrInvalidPKCS7Padding + } + for i := 0; i < n; i++ { + if data[len(data)-n+i] != c { + return nil, ErrInvalidPKCS7Padding + } + } + return data[:len(data)-n], nil +} + +func (w *WXUserDataCrypt) Decrypt(encryptedData, iv string) (*WxUserInfo, error) { + aesKey, err := base64.StdEncoding.DecodeString(w.sessionKey) + if err != nil { + return nil, err + } + cipherText, err := base64.StdEncoding.DecodeString(encryptedData) + if err != nil { + return nil, err + } + ivBytes, err := base64.StdEncoding.DecodeString(iv) + if err != nil { + return nil, err + } + block, err := aes.NewCipher(aesKey) + if err != nil { + return nil, err + } + mode := cipher.NewCBCDecrypter(block, ivBytes) + mode.CryptBlocks(cipherText, cipherText) + cipherText, err = pkcs7Unpad(cipherText, block.BlockSize()) + if err != nil { + return nil, err + } + var userInfo WxUserInfo + err = json.Unmarshal(cipherText, &userInfo) + if err != nil { + return nil, err + } + if userInfo.Watermark.AppID != w.appID { + return nil, ErrAppIDNotMatch + } + return &userInfo, nil +} \ No newline at end of file -- libgit2 0.21.0