package vend import ( "encoding/base64" "encoding/json" "fmt" "github.com/gin-gonic/gin" "io/ioutil" "net/http" "recook/internal/back" "recook/internal/dbc" "recook/internal/define" "recook/internal/model/vend" "recook/tools" "time" ) const WxMiniUserOpenIDUrl = "https://api.weixin.qq.com/sns/jscode2session?appid=%v&secret=%v&js_code=%v&grant_type=authorization_code" type miniLoginParam struct { AuthCode string `json:"auth_code" validator:"required"` } type openidResp struct { OpenID string `json:"openid" validate:"required"` UnionId string `json:"unionId" validate:"required"` SessionKey string `json:"session_key"` ErrMsg string `json:"errmsg"` } //通过小程序登录 func LoginByMiniProgram(c *gin.Context) { var p miniLoginParam if err := tools.Params(&p, c); err != nil { back.Fail(c, err.Error()) return } response, err := http.Get(fmt.Sprintf(WxMiniUserOpenIDUrl, define.WxMiniProgramAppID, define.WxMiniProgramAppSecret, p.AuthCode)) if err != nil { back.Err(c, err.Error()) return } defer func() { _ = response.Body.Close() }() body, err := ioutil.ReadAll(response.Body) if err != nil { back.Fail(c, err.Error()) return } var resp openidResp if err = json.Unmarshal(body, &resp); err != nil { back.Fail(c, err.Error()) return } if len(resp.ErrMsg) > 0 { back.Fail(c, "微信授权失败"+resp.ErrMsg) return } //将openid信息插入到数据库 var gysUsersThird vend.GysUsersThird dbc.DB.First(&gysUsersThird, "`type` = ? and code=?", vend.GysUsersThirdTypeWxApp, resp.OpenID) if gysUsersThird.Id <= 0 { gysUsersThird.Code = resp.OpenID gysUsersThird.Type = vend.GysUsersThirdTypeWxApp dbc.DB.Create(&gysUsersThird) } var sessionId = tools.MD5(resp.OpenID) dbc.Rds.Set(fmt.Sprintf("wxapp:session_key:%v:%v", define.WxMiniProgramAppID, resp.OpenID), resp.SessionKey, time.Hour*24) if gysUsersThird.UserId > 0 { // 缓存session_key 1天 dbc.Rds.Set(fmt.Sprintf("wxapp:login:gys:%v:gysid", gysUsersThird.UserId), sessionId, time.Hour*24) } //下面返回的信息,会在以后的请求头中。 back.Suc(c, "", gin.H{ "session_id": sessionId, "gys_id": gysUsersThird.UserId, "openId": resp.OpenID, }) return } type argsCrypto struct { EncryptedData string `json:"encryptedData" form:"encryptedData"` Iv string `json:"iv" form:"iv"` OpenId string `json:"openId" form:"openId"` } type UserPhone struct { CountryCode string `json:"countryCode"` PhoneNumber string `json:"phoneNumber"` PurePhoneNumber string `json:"purePhoneNumber"` Watermark struct { Appid string `json:"appid"` Timestamp int64 `json:"timestamp"` } `json:"watermark"` } // @Style 设置手机号 func Phone(c *gin.Context) { args := argsCrypto{} if err := tools.Params(&args, c); err != nil { back.Fail(c, err.Error()) return } gysUserThird := vend.GysUsersThird{} dbc.DB.First(&gysUserThird, "`type` = ? and code = ?", vend.GysUsersThirdTypeWxApp, args.OpenId) if gysUserThird.UserId > 0 { back.Suc(c, "操作成功", gin.H{ "gys_id": gysUserThird.UserId, }) return } sessionKey := dbc.Rds.Get(fmt.Sprintf("wxapp:session_key:%v:%v", define.WxMiniProgramAppID, args.OpenId)).Val() decodeString, _ := base64.StdEncoding.DecodeString(args.EncryptedData) key, _ := base64.StdEncoding.DecodeString(sessionKey) iv, _ := base64.StdEncoding.DecodeString(args.Iv) jsonData, _ := tools.AesCBCDecrypt(decodeString, key, iv) userPhone := UserPhone{} json.Unmarshal(jsonData, &userPhone) if userPhone.Watermark.Appid != define.WxMiniProgramAppID { back.Fail(c, "登录超时") return } vendData := vend.GysUsers{} dbc.DB.First(&vendData, "username = ?", userPhone.PhoneNumber) if vendData.ID <= 0 { vendData.Username = userPhone.PhoneNumber vendData.Password = tools.RandStr(6, "0123456789") dbc.DB.Create(&vendData) if vendData.ID <= 0 { back.Fail(c, "网络异常") return } } dbc.DB.Model(&gysUserThird).Updates(&vend.GysUsersThird{ UserId: vendData.ID, }) // 缓存session_key 1天 var sessionId = tools.MD5(args.OpenId) dbc.Rds.Set(fmt.Sprintf("wxapp:login:gys:%v:gysid", vendData.ID), sessionId, time.Hour*24) back.Suc(c, "操作成功", gin.H{ "gys_id": vendData.ID, }) }