kefu/tools/wechat/wechat.go

108 lines
3.1 KiB
Go
Raw Normal View History

2024-12-10 02:50:12 +00:00
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
}