由微信公众号授权鉴权成功后,我们就可以拿到用户的基本数据,主要提取用户的微信公众号openid,因为它是唯一的。
功能
在mk代码之前,先要把实现的功能大概列出来: 1、5分钟之内只能获取一个平台code 2、获取code时,是否创建新的账号
5分钟之内只能获取一个平台code
这个功能主要是利用redis保持下发状态, 定义一个存储redis数据的函数:
func SetRedisByString(key string, value string, timeOut time.Duration) bool {
err := RDB.Set(ctx, key, value, timeOut).Err()
if err != nil {
logger.Logger.Error(fmt.Sprintf("redis key %v 设置失败, %v", key, err))
return false
}
return true
}
定义一个获取redis数据函数,当用户发送信息给微信公众号时,判断是否已经下发。
func GetRedisByString(key string) (bool, string) {
count, err := RDB.Get(ctx, key).Result()
if err == redis.Nil {
fmt.Println("key2 does not exist")
logger.Logger.Info(fmt.Sprintf("redis key %v不存在", key))
return false, "empty"
} else if err != nil {
logger.Logger.Error(fmt.Sprintf("redis key %v 获取失败 %v", key, err))
return false, "error"
} else {
return true, count
}
}
获取code时,是否创建新的账号
是否创建新账号得判断用户的微信公众号openid是否已经存在。定义一个创建账号函数:
// 注册新用户
func CreateUser(id string, pbOpenId string) bool {
user := &model.User{
Id: id,
Enable: true,
PbOpenId: pbOpenId,
}
has, e := datasource.Engine.Where("pb_openid = ?", pbOpenId).Get(&model.User{})
if e != nil {
logger.Logger.Error(fmt.Sprintf("查询用户失败%v, error: %v", pbOpenId, e.Error()))
return false
}
if has == true {
logger.Logger.Info("用户已存在")
return true
}
_, err := datasource.Engine.Insert(*user)
if err != nil {
logger.Logger.Error(fmt.Sprintf("创建新用户失败 %v", err))
return false
}
logger.Logger.Info("创建新用户成功")
return true
}
如何关联小程序?
在创建用户时,服务会根据用户公众号openid去生成一个微信小程序的二维码,小程序页面链接携带这个用户公众号openid,然后当用户用微信去扫这个二维码时,就可以实现关联的效果。 定义一个生成二维码函数:
func GencQr(attoken string, id string) {
if attoken == "" {
return
}
client := resty.New() // 创建一个restry客户端
resp, err :=
client.R().EnableTrace().SetBody([]byte(
fmt.Sprintf(`{
"path":"/pages/index/index?noticeId=%v",
"width":430
} `, id))).Post(GEN_QR + attoken)
if err != nil {
fmt.Printf("请求接口失败:%v\n", err)
return
}
fmt.Println("解析成功: ", id, attoken)
ioutil.WriteFile("public/"+id+".png", []byte(resp.String()), 0666)
}
当用户去扫码时,其实系统已经存在账号,因此我们只需要修改账号信息就好了,定义一个修改账号信息函数:
func UpdateUser(id string, info *model.User) (bool, int) {
_, err := datasource.Engine.Cols("ap_openid", "nick_name").Where("id = ?", id).Update(&model.User{
ApOpenId: info.ApOpenId,
NickName: info.NickName,
})
if err != nil {
logger.Logger.Error(fmt.Sprintf("更新用户信息失败, Openid: %v, %v", id, err))
return false, config.STATUS_ERROR
}
logger.Logger.Error("更新用户信息成功")
return true, config.STATUS_SUE
}
根据微信小程序文档 可以定义一个获取小程序的openid函数:
func getWXOpen(code string, nickName string) string {
wxConfig := config.BASE_CONFIG.WxConfig
fmt.Println("wxConfig==", wxConfig)
url := fmt.Sprintf("%v&appid=%v&secret=%v&js_code=%v", URL, wxConfig.Appid, wxConfig.AppSecret, code)
resp, err := http.Get(url)
if err != nil {
logger.Logger.Error(fmt.Sprintf("获取openId 失败:%v", nickName))
return ""
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
user := &model.User{}
jer := json.Unmarshal(body, user)
if jer != nil {
logger.Logger.Error(fmt.Sprintf("获取openId 失败:%v", jer))
return ""
}
if resp.StatusCode == 200 {
logger.Logger.Info(fmt.Sprintf("获取openId 成功:%v", user))
return user.OpenId
}
logger.Logger.Error(fmt.Sprintf("获取openId 失败:%v", nickName))
return ""
}
最后
创建账号的功能就ok了,实现微信小程序、微信公众号关联账号的功能。现在你可以用微信公众号获取指令的方式去登录平台,接下来要实现的就是通过微信小程序扫码登录的功能。