package wechat import ( "crypto/sha1" "encoding/hex" "encoding/json" "errors" "fmt" "github.com/silenceper/wechat/v2" "github.com/silenceper/wechat/v2/cache" offConfig "github.com/silenceper/wechat/v2/officialaccount/config" "github.com/silenceper/wechat/v2/officialaccount/oauth" "kefu/tools" "log" "net/url" "sort" ) type AccessToken struct { AccessToken string `json:"access_token"` ExpiresIn uint `json:"expires_in"` } type Ticket struct { Ticket string `json:"ticket"` ExpireSeconds uint `json:"expire_seconds"` Url string `json:"url"` } /** 获取access_token */ func GetAccessToken(appId, appSecret string) *AccessToken { url := fmt.Sprintf( "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", appId, appSecret) accessToken := tools.Get(url) token := &AccessToken{} json.Unmarshal([]byte(accessToken), token) return token } /** 获取临时二维码ticket */ func CreateQrImgUrl(accessToken, accountInfo string) { api := "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + accessToken data := fmt.Sprintf( "{\"expire_seconds\": 604800, \"action_name\": \"QR_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": \"%s\"}}}", accountInfo) result, _ := tools.Post(api, "application/json;charset=utf-8", []byte(data)) ticket := &Ticket{} json.Unmarshal([]byte(result), ticket) imgUrl := "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" + url.QueryEscape(ticket.Ticket) log.Println(ticket.Ticket, imgUrl) } /** 验证签名 */ func CheckWechatSign(token, signature, timestamp, nonce, echostr string) (string, error) { //将token、timestamp、nonce三个参数进行字典序排序 var tempArray = []string{token, timestamp, nonce} sort.Strings(tempArray) //将三个参数字符串拼接成一个字符串进行sha1加密 var sha1String string = "" for _, v := range tempArray { sha1String += v } h := sha1.New() h.Write([]byte(sha1String)) sha1String = hex.EncodeToString(h.Sum([]byte(""))) //获得加密后的字符串可与signature对比 if sha1String == signature { return echostr, nil } return "", errors.New("微信API验证失败") } /** 公众号网页授权封装函数 所需参数解释: appid,appsecret,token这三个是公众号后台设置的 code是网页授权回跳链接带回来的,code作为换取access_token的票据,每次用户授权带上的 code 将不一样,code只能使用一次,5分钟未被使用自动过期。 cache是内存形式存储access_token cache := cache2.NewMemory() */ func GetWechatOfficialNickname(appId, appSecret, token, code string, cache cache.Cache) (userinfo oauth.UserInfo, err error) { cfg := &offConfig.Config{ AppID: appId, AppSecret: appSecret, Token: token, //EncodingAESKey: "xxxx", Cache: cache, } wc := wechat.NewWechat() officialAccount := wc.GetOfficialAccount(cfg) oauth := officialAccount.GetOauth() accessToken, err := oauth.GetUserAccessToken(code) if err != nil { return } userinfo, err = oauth.GetUserInfo(accessToken.AccessToken, accessToken.OpenID, "") if err != nil { return } return }