108 lines
3.1 KiB
Go
108 lines
3.1 KiB
Go
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
|
||
}
|