Commit 2decca18a614cf664e83c446a6614bfa61bb89b0
1 parent
cda08d33
Exists in
master
接入微信登录
Showing
6 changed files
with
253 additions
and
19 deletions
Show diff stats
src/HttpServer/logic/constdef.go
src/HttpServer/logic/datadef.go
| ... | ... | @@ -14,6 +14,20 @@ const ( |
| 14 | 14 | |
| 15 | 15 | ) |
| 16 | 16 | |
| 17 | +type WechatLoginReq struct { | |
| 18 | + Channel_id int `json:"channel_id"` | |
| 19 | + Invite_type int `json:"invite_type"` | |
| 20 | + Invite_res_id int `json:"invite_res_id"` | |
| 21 | + User_invite_uid int `json:"user_invite_uid"` | |
| 22 | + Code string `json:"code"` | |
| 23 | + Signature string `json:"signature"` | |
| 24 | + Iv string `json:"iv"` | |
| 25 | + Raw_data string `json:"raw_data"` | |
| 26 | + Encrypted_data string `json:"encrypted_data"` | |
| 27 | + Token string `json:"token"` | |
| 28 | + Version string `json:"version"` | |
| 29 | +} | |
| 30 | + | |
| 17 | 31 | type UserLoginReq struct { |
| 18 | 32 | Channel_id int `json:"channel_id"` |
| 19 | 33 | Invite_type int `json:"invite_type"` |
| ... | ... | @@ -23,9 +37,6 @@ type UserLoginReq struct { |
| 23 | 37 | RefAppId int `json:"refAppId"` |
| 24 | 38 | Code string `json:"code"` |
| 25 | 39 | Token string `json:"token"` |
| 26 | - Logintype int `json:"logintype"` | |
| 27 | - Useraccount string `json:"useraccount"` | |
| 28 | - Userpwd string `json:"userpwd"` | |
| 29 | 40 | Version string `json:"version"` |
| 30 | 41 | |
| 31 | 42 | } | ... | ... |
src/HttpServer/logic/errordef.go
src/HttpServer/logic/httpserver.go
| ... | ... | @@ -29,7 +29,8 @@ func CheckErr(err error) { |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | 31 | func startServerHttpServe() { |
| 32 | - http.HandleFunc("/catcafe/login", UserLogin) //登录 | |
| 32 | + http.HandleFunc("/catcafe/login", UserLogin) //游客登录 | |
| 33 | + http.HandleFunc("/catcafe/wechatlogin", Wechatlogin) //微信登录 | |
| 33 | 34 | http.HandleFunc("/catcafe/user/saveUserData", SaveUserData) //保存用户数据 |
| 34 | 35 | http.HandleFunc("/catcafe/data/saveData", SaveData) //保存游戏自定义数据 |
| 35 | 36 | http.HandleFunc("/catcafe/data/getData", GetData) //获取自定义数据 |
| ... | ... | @@ -60,6 +61,18 @@ func startServerHttpServe() { |
| 60 | 61 | } |
| 61 | 62 | |
| 62 | 63 | |
| 64 | +func Wechatlogin(w http.ResponseWriter, r *http.Request) { | |
| 65 | + | |
| 66 | + result, _ := ioutil.ReadAll(r.Body) | |
| 67 | + r.Body.Close() | |
| 68 | + | |
| 69 | + s := string(result) | |
| 70 | + logger.Info("Wechatlogin , body:%v,uuid=%v", s) | |
| 71 | + | |
| 72 | + HandleWechatlogin(w,s) | |
| 73 | +} | |
| 74 | + | |
| 75 | + | |
| 63 | 76 | func QueryPlayerData(w http.ResponseWriter, r *http.Request) { |
| 64 | 77 | |
| 65 | 78 | result, _ := ioutil.ReadAll(r.Body) | ... | ... |
src/HttpServer/logic/logic.go
| ... | ... | @@ -25,6 +25,44 @@ func init() { |
| 25 | 25 | } |
| 26 | 26 | |
| 27 | 27 | |
| 28 | +func InitUserExt(req *UserLoginReq,resp *UserLoginResp,uuid int) { | |
| 29 | + var extdata UserExtData | |
| 30 | + extdata.User_id = uuid | |
| 31 | + extdata.Lv = 1 | |
| 32 | + extdata.Bean = 0 | |
| 33 | + extdata.Coin = 0 | |
| 34 | + extdata.Exp = 0 | |
| 35 | + extdata.Hot = 0 | |
| 36 | + extdata.Invite_uid = req.User_invite_uid | |
| 37 | + extdata.LoveExp = 0 | |
| 38 | + extdata.Reg_time = int(time.Now().Unix()) | |
| 39 | + extdata.ShopNum = 0 | |
| 40 | + extdata.User_channel = req.Channel_id | |
| 41 | + extdata.User_is_black = 0 | |
| 42 | + extdata.User_reg_time = int(time.Now().Unix()) | |
| 43 | + extdata.User_scene = req.Scene | |
| 44 | + resp.Result.Data.Extdata = extdata | |
| 45 | + //保存 | |
| 46 | + udata :=new(UserData) | |
| 47 | + udata.Scene = extdata.User_scene | |
| 48 | + udata.Hot = extdata.Hot | |
| 49 | + udata.Exp = extdata.Exp | |
| 50 | + udata.Coin = extdata.Coin | |
| 51 | + udata.Bean = extdata.Bean | |
| 52 | + udata.Lv = extdata.Lv | |
| 53 | + udata.Channel = extdata.User_channel | |
| 54 | + udata.InviteUid = extdata.Invite_uid | |
| 55 | + udata.Isblack = extdata.User_is_black | |
| 56 | + udata.Loevexp = extdata.LoveExp | |
| 57 | + udata.Regtime = extdata.Reg_time | |
| 58 | + udata.Shopnum = extdata.ShopNum | |
| 59 | + udata.Userid = extdata.User_id | |
| 60 | + udata.UserInviteId = extdata.User_invite_uid | |
| 61 | + udata.Userregtime = extdata.User_reg_time | |
| 62 | + | |
| 63 | + SaveUserExt(udata) | |
| 64 | +} | |
| 65 | + | |
| 28 | 66 | |
| 29 | 67 | func InitTourist(req *UserLoginReq,resp *UserLoginResp) { |
| 30 | 68 | //首先生成user_base_data |
| ... | ... | @@ -43,6 +81,28 @@ func InitTourist(req *UserLoginReq,resp *UserLoginResp) { |
| 43 | 81 | |
| 44 | 82 | SetTouristUid(req.Token,basedata.User_id) |
| 45 | 83 | //然后生成user_ext_data |
| 84 | + InitUserExt(req,resp,basedata.User_id) | |
| 85 | + | |
| 86 | +} | |
| 87 | + | |
| 88 | +//微信登录账户初始化 | |
| 89 | +func InitWeChatUser(req *WechatLoginReq,resp *UserLoginResp,uinfo *WxUserInfo) { | |
| 90 | + //首先生成user_base_data | |
| 91 | + var basedata UserBaseData | |
| 92 | + basedata.User_id = GetNewUUid() | |
| 93 | + basedata.User_avatar_url = uinfo.AvatarURL | |
| 94 | + basedata.User_city = uinfo.City | |
| 95 | + basedata.User_gender = uinfo.Gender | |
| 96 | + basedata.User_nickname = uinfo.NickName | |
| 97 | + basedata.User_openid = uinfo.OpenID | |
| 98 | + basedata.User_token = req.Token | |
| 99 | + resp.Result.Data.Dasedata = basedata | |
| 100 | + //保存base data | |
| 101 | + basic, _ := json.Marshal(&basedata) | |
| 102 | + SaveUserBasic(basedata.User_id,string(basic)) | |
| 103 | + | |
| 104 | + SetTouristUid(uinfo.OpenID,basedata.User_id) | |
| 105 | + //然后生成user_ext_data | |
| 46 | 106 | var extdata UserExtData |
| 47 | 107 | extdata.User_id = basedata.User_id |
| 48 | 108 | extdata.Lv = 1 |
| ... | ... | @@ -57,7 +117,7 @@ func InitTourist(req *UserLoginReq,resp *UserLoginResp) { |
| 57 | 117 | extdata.User_channel = req.Channel_id |
| 58 | 118 | extdata.User_is_black = 0 |
| 59 | 119 | extdata.User_reg_time = int(time.Now().Unix()) |
| 60 | - extdata.User_scene = req.Scene | |
| 120 | + extdata.User_scene = 0 | |
| 61 | 121 | resp.Result.Data.Extdata = extdata |
| 62 | 122 | //保存 |
| 63 | 123 | udata :=new(UserData) |
| ... | ... | @@ -81,6 +141,65 @@ func InitTourist(req *UserLoginReq,resp *UserLoginResp) { |
| 81 | 141 | |
| 82 | 142 | } |
| 83 | 143 | |
| 144 | +//处理微信登录 | |
| 145 | +func HandleWechatlogin(w http.ResponseWriter, data string) { | |
| 146 | + | |
| 147 | + SetHeader(w) | |
| 148 | + var resp UserLoginResp | |
| 149 | + resp.Status = "true" | |
| 150 | + resp.Result.Code = ERROR_OK | |
| 151 | + var rdata WechatLoginReq | |
| 152 | + err := json.Unmarshal([]byte(data), &rdata) | |
| 153 | + for { | |
| 154 | + if err != nil { | |
| 155 | + logger.Error("HandleWechatlogin json unmarshal failed=%v", err) | |
| 156 | + resp.Result.Code = ERROR_JSONUNMASHFAILED | |
| 157 | + break | |
| 158 | + } | |
| 159 | + | |
| 160 | + pc := NewWXUserDataCrypt(WETCHATAPPID, WETCHATSERCRT) | |
| 161 | + userInfo, err := pc.Decrypt(rdata.Encrypted_data, rdata.Iv) | |
| 162 | + if err != nil { | |
| 163 | + logger.Error("HandleWechatlogin wechatloginfailed failed=%v", err) | |
| 164 | + resp.Result.Code = ERROR_WECHATLOGINFAILED | |
| 165 | + break | |
| 166 | + } | |
| 167 | + logger.Info("HandleWechatlogin userInfo=%v",userInfo) | |
| 168 | + | |
| 169 | + uuid,_ := GetTouristUid(userInfo.OpenID) | |
| 170 | + if uuid == 0 { | |
| 171 | + //新的账号 需要初始化保存 | |
| 172 | + InitWeChatUser(&rdata,&resp,userInfo) | |
| 173 | + }else { | |
| 174 | + //读取数据 | |
| 175 | + basic,err := GetUserBasic(uuid) | |
| 176 | + if err != nil { | |
| 177 | + logger.Error("HandleWechatlogin getbasic failed=%v", err) | |
| 178 | + resp.Result.Code = ERROR_GETUSERBASICFAILED | |
| 179 | + break | |
| 180 | + } | |
| 181 | + resp.Result.Data.Dasedata = *basic | |
| 182 | + | |
| 183 | + ext,err := GetUserExt(uuid) | |
| 184 | + if err != nil { | |
| 185 | + logger.Error("HandleWechatlogin getext failed=%v", err) | |
| 186 | + resp.Result.Code = ERROR_GETUSEREXTFAILED | |
| 187 | + break | |
| 188 | + } | |
| 189 | + resp.Result.Data.Extdata = *ext | |
| 190 | + | |
| 191 | + m_userInfo.Set(uint32(ext.User_id),ext) | |
| 192 | + } | |
| 193 | + | |
| 194 | + resp.Result.Code = ERROR_OK | |
| 195 | + break | |
| 196 | + } | |
| 197 | + | |
| 198 | + //回包 | |
| 199 | + respstr, _ := json.Marshal(&resp) | |
| 200 | + fmt.Fprint(w, string(respstr)) | |
| 201 | +} | |
| 202 | + | |
| 84 | 203 | //处理游客登录 |
| 85 | 204 | func HandleTouristLogin(w http.ResponseWriter, req *UserLoginReq,resp *UserLoginResp) { |
| 86 | 205 | |
| ... | ... | @@ -134,23 +253,11 @@ func HandleUserLogin(w http.ResponseWriter, data string) { |
| 134 | 253 | break |
| 135 | 254 | } |
| 136 | 255 | |
| 137 | - if rdata.Logintype ==LOGIN_TYPE_TOURIST { | |
| 138 | - //游客登录 | |
| 139 | - HandleTouristLogin(w,&rdata,&resp) | |
| 140 | - break | |
| 141 | - } | |
| 142 | 256 | |
| 143 | - if rdata.Logintype == LOGIN_TYPE_ACCOUNT { | |
| 144 | - //账号密码登录 | |
| 257 | + HandleTouristLogin(w,&rdata,&resp) | |
| 145 | 258 | |
| 146 | - break | |
| 147 | - } | |
| 148 | 259 | |
| 149 | - if rdata.Logintype == LOGIN_TYPE_WECHAT { | |
| 150 | - //微信登录 | |
| 151 | 260 | |
| 152 | - break | |
| 153 | - } | |
| 154 | 261 | |
| 155 | 262 | |
| 156 | 263 | } |
| ... | ... | @@ -301,7 +408,7 @@ func HandlegetData(w http.ResponseWriter, data string) { |
| 301 | 408 | } |
| 302 | 409 | |
| 303 | 410 | func GetAccessToken() string{ |
| 304 | - //首先从缓存取 | |
| 411 | + //首先从缓存取kwiffwiffiaowosfwkfko | |
| 305 | 412 | exist,err := redishandler.GetRedisClient().Exists(redis.MSG_CKECK_ACCESSTOKEN) |
| 306 | 413 | if err != nil { |
| 307 | 414 | logger.Error("GetAccessToken err=%v",err) | ... | ... |
| ... | ... | @@ -0,0 +1,98 @@ |
| 1 | +package logic | |
| 2 | + | |
| 3 | +import ( | |
| 4 | + "crypto/aes" | |
| 5 | + "crypto/cipher" | |
| 6 | + "encoding/base64" | |
| 7 | + "encoding/json" | |
| 8 | + "errors" | |
| 9 | +) | |
| 10 | + | |
| 11 | +var ( | |
| 12 | + ErrAppIDNotMatch = errors.New("app id not match") | |
| 13 | + ErrInvalidBlockSize = errors.New("invalid block size") | |
| 14 | + ErrInvalidPKCS7Data = errors.New("invalid PKCS7 data") | |
| 15 | + ErrInvalidPKCS7Padding = errors.New("invalid padding on input") | |
| 16 | +) | |
| 17 | + | |
| 18 | +type WxUserInfo struct { | |
| 19 | + OpenID string `json:"openId"` | |
| 20 | + UnionID string `json:"unionId"` | |
| 21 | + NickName string `json:"nickName"` | |
| 22 | + Gender int `json:"gender"` | |
| 23 | + City string `json:"city"` | |
| 24 | + Province string `json:"province"` | |
| 25 | + Country string `json:"country"` | |
| 26 | + AvatarURL string `json:"avatarUrl"` | |
| 27 | + Language string `json:"language"` | |
| 28 | + Watermark struct { | |
| 29 | + Timestamp int64 `json:"timestamp"` | |
| 30 | + AppID string `json:"appid"` | |
| 31 | + } `json:"watermark"` | |
| 32 | +} | |
| 33 | + | |
| 34 | +type WXUserDataCrypt struct { | |
| 35 | + appID, sessionKey string | |
| 36 | +} | |
| 37 | + | |
| 38 | +func NewWXUserDataCrypt(appID, sessionKey string) *WXUserDataCrypt { | |
| 39 | + return &WXUserDataCrypt{ | |
| 40 | + appID: appID, | |
| 41 | + sessionKey: sessionKey, | |
| 42 | + } | |
| 43 | +} | |
| 44 | + | |
| 45 | +// pkcs7Unpad returns slice of the original data without padding | |
| 46 | +func pkcs7Unpad(data []byte, blockSize int) ([]byte, error) { | |
| 47 | + if blockSize <= 0 { | |
| 48 | + return nil, ErrInvalidBlockSize | |
| 49 | + } | |
| 50 | + if len(data)%blockSize != 0 || len(data) == 0 { | |
| 51 | + return nil, ErrInvalidPKCS7Data | |
| 52 | + } | |
| 53 | + c := data[len(data)-1] | |
| 54 | + n := int(c) | |
| 55 | + if n == 0 || n > len(data) { | |
| 56 | + return nil, ErrInvalidPKCS7Padding | |
| 57 | + } | |
| 58 | + for i := 0; i < n; i++ { | |
| 59 | + if data[len(data)-n+i] != c { | |
| 60 | + return nil, ErrInvalidPKCS7Padding | |
| 61 | + } | |
| 62 | + } | |
| 63 | + return data[:len(data)-n], nil | |
| 64 | +} | |
| 65 | + | |
| 66 | +func (w *WXUserDataCrypt) Decrypt(encryptedData, iv string) (*WxUserInfo, error) { | |
| 67 | + aesKey, err := base64.StdEncoding.DecodeString(w.sessionKey) | |
| 68 | + if err != nil { | |
| 69 | + return nil, err | |
| 70 | + } | |
| 71 | + cipherText, err := base64.StdEncoding.DecodeString(encryptedData) | |
| 72 | + if err != nil { | |
| 73 | + return nil, err | |
| 74 | + } | |
| 75 | + ivBytes, err := base64.StdEncoding.DecodeString(iv) | |
| 76 | + if err != nil { | |
| 77 | + return nil, err | |
| 78 | + } | |
| 79 | + block, err := aes.NewCipher(aesKey) | |
| 80 | + if err != nil { | |
| 81 | + return nil, err | |
| 82 | + } | |
| 83 | + mode := cipher.NewCBCDecrypter(block, ivBytes) | |
| 84 | + mode.CryptBlocks(cipherText, cipherText) | |
| 85 | + cipherText, err = pkcs7Unpad(cipherText, block.BlockSize()) | |
| 86 | + if err != nil { | |
| 87 | + return nil, err | |
| 88 | + } | |
| 89 | + var userInfo WxUserInfo | |
| 90 | + err = json.Unmarshal(cipherText, &userInfo) | |
| 91 | + if err != nil { | |
| 92 | + return nil, err | |
| 93 | + } | |
| 94 | + if userInfo.Watermark.AppID != w.appID { | |
| 95 | + return nil, ErrAppIDNotMatch | |
| 96 | + } | |
| 97 | + return &userInfo, nil | |
| 98 | +} | |
| 0 | 99 | \ No newline at end of file | ... | ... |