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,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 | type UserLoginReq struct { | 31 | type UserLoginReq struct { |
18 | Channel_id int `json:"channel_id"` | 32 | Channel_id int `json:"channel_id"` |
19 | Invite_type int `json:"invite_type"` | 33 | Invite_type int `json:"invite_type"` |
@@ -23,9 +37,6 @@ type UserLoginReq struct { | @@ -23,9 +37,6 @@ type UserLoginReq struct { | ||
23 | RefAppId int `json:"refAppId"` | 37 | RefAppId int `json:"refAppId"` |
24 | Code string `json:"code"` | 38 | Code string `json:"code"` |
25 | Token string `json:"token"` | 39 | Token string `json:"token"` |
26 | - Logintype int `json:"logintype"` | ||
27 | - Useraccount string `json:"useraccount"` | ||
28 | - Userpwd string `json:"userpwd"` | ||
29 | Version string `json:"version"` | 40 | Version string `json:"version"` |
30 | 41 | ||
31 | } | 42 | } |
src/HttpServer/logic/errordef.go
@@ -35,4 +35,5 @@ const ( | @@ -35,4 +35,5 @@ const ( | ||
35 | ERROR_FRIENDNOTFRIEND = 30 //不是好友 | 35 | ERROR_FRIENDNOTFRIEND = 30 //不是好友 |
36 | ERROR_FRIENDDELFRIENDFAILED = 31 //删除好友失败 | 36 | ERROR_FRIENDDELFRIENDFAILED = 31 //删除好友失败 |
37 | ERROR_FRIENDGETFRIENDINFOFAILED = 32 //获取好友信息失败 | 37 | ERROR_FRIENDGETFRIENDINFOFAILED = 32 //获取好友信息失败 |
38 | + ERROR_WECHATLOGINFAILED = 33 //获取好友信息失败 | ||
38 | ) | 39 | ) |
39 | \ No newline at end of file | 40 | \ No newline at end of file |
src/HttpServer/logic/httpserver.go
@@ -29,7 +29,8 @@ func CheckErr(err error) { | @@ -29,7 +29,8 @@ func CheckErr(err error) { | ||
29 | } | 29 | } |
30 | 30 | ||
31 | func startServerHttpServe() { | 31 | func startServerHttpServe() { |
32 | - http.HandleFunc("/catcafe/login", UserLogin) //登录 | 32 | + http.HandleFunc("/catcafe/login", UserLogin) //游客登录 |
33 | + http.HandleFunc("/catcafe/wechatlogin", Wechatlogin) //微信登录 | ||
33 | http.HandleFunc("/catcafe/user/saveUserData", SaveUserData) //保存用户数据 | 34 | http.HandleFunc("/catcafe/user/saveUserData", SaveUserData) //保存用户数据 |
34 | http.HandleFunc("/catcafe/data/saveData", SaveData) //保存游戏自定义数据 | 35 | http.HandleFunc("/catcafe/data/saveData", SaveData) //保存游戏自定义数据 |
35 | http.HandleFunc("/catcafe/data/getData", GetData) //获取自定义数据 | 36 | http.HandleFunc("/catcafe/data/getData", GetData) //获取自定义数据 |
@@ -60,6 +61,18 @@ func startServerHttpServe() { | @@ -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 | func QueryPlayerData(w http.ResponseWriter, r *http.Request) { | 76 | func QueryPlayerData(w http.ResponseWriter, r *http.Request) { |
64 | 77 | ||
65 | result, _ := ioutil.ReadAll(r.Body) | 78 | result, _ := ioutil.ReadAll(r.Body) |
src/HttpServer/logic/logic.go
@@ -25,6 +25,44 @@ func init() { | @@ -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 | func InitTourist(req *UserLoginReq,resp *UserLoginResp) { | 67 | func InitTourist(req *UserLoginReq,resp *UserLoginResp) { |
30 | //首先生成user_base_data | 68 | //首先生成user_base_data |
@@ -43,6 +81,28 @@ func InitTourist(req *UserLoginReq,resp *UserLoginResp) { | @@ -43,6 +81,28 @@ func InitTourist(req *UserLoginReq,resp *UserLoginResp) { | ||
43 | 81 | ||
44 | SetTouristUid(req.Token,basedata.User_id) | 82 | SetTouristUid(req.Token,basedata.User_id) |
45 | //然后生成user_ext_data | 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 | var extdata UserExtData | 106 | var extdata UserExtData |
47 | extdata.User_id = basedata.User_id | 107 | extdata.User_id = basedata.User_id |
48 | extdata.Lv = 1 | 108 | extdata.Lv = 1 |
@@ -57,7 +117,7 @@ func InitTourist(req *UserLoginReq,resp *UserLoginResp) { | @@ -57,7 +117,7 @@ func InitTourist(req *UserLoginReq,resp *UserLoginResp) { | ||
57 | extdata.User_channel = req.Channel_id | 117 | extdata.User_channel = req.Channel_id |
58 | extdata.User_is_black = 0 | 118 | extdata.User_is_black = 0 |
59 | extdata.User_reg_time = int(time.Now().Unix()) | 119 | extdata.User_reg_time = int(time.Now().Unix()) |
60 | - extdata.User_scene = req.Scene | 120 | + extdata.User_scene = 0 |
61 | resp.Result.Data.Extdata = extdata | 121 | resp.Result.Data.Extdata = extdata |
62 | //保存 | 122 | //保存 |
63 | udata :=new(UserData) | 123 | udata :=new(UserData) |
@@ -81,6 +141,65 @@ func InitTourist(req *UserLoginReq,resp *UserLoginResp) { | @@ -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 | func HandleTouristLogin(w http.ResponseWriter, req *UserLoginReq,resp *UserLoginResp) { | 204 | func HandleTouristLogin(w http.ResponseWriter, req *UserLoginReq,resp *UserLoginResp) { |
86 | 205 | ||
@@ -134,23 +253,11 @@ func HandleUserLogin(w http.ResponseWriter, data string) { | @@ -134,23 +253,11 @@ func HandleUserLogin(w http.ResponseWriter, data string) { | ||
134 | break | 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,7 +408,7 @@ func HandlegetData(w http.ResponseWriter, data string) { | ||
301 | } | 408 | } |
302 | 409 | ||
303 | func GetAccessToken() string{ | 410 | func GetAccessToken() string{ |
304 | - //首先从缓存取 | 411 | + //首先从缓存取kwiffwiffiaowosfwkfko |
305 | exist,err := redishandler.GetRedisClient().Exists(redis.MSG_CKECK_ACCESSTOKEN) | 412 | exist,err := redishandler.GetRedisClient().Exists(redis.MSG_CKECK_ACCESSTOKEN) |
306 | if err != nil { | 413 | if err != nil { |
307 | logger.Error("GetAccessToken err=%v",err) | 414 | logger.Error("GetAccessToken err=%v",err) |
@@ -0,0 +1,98 @@ | @@ -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 | \ No newline at end of file | 99 | \ No newline at end of file |