package jssdk import ( "crypto/sha1" "encoding/json" "fmt" "io" "io/ioutil" "math/rand" "net/http" "strconv" "time" ) var appid string var appsecret string type Wxconfig struct { appId string appSecret string url string } type json1 struct { Expire_time int Jsapi_ticket string } type json2 struct { Expire_time int Access_token string } type token struct { Access_token string Expires_in int } type ticket struct { Errcode int Errmsg string Ticket string Expires_in int } type signPackage struct { AppId string `json:"appId"` NonceStr string `json:"nonceStr"` Timestamp int `json:"timestamp"` Url string `json:"url"` Signature string `json:"signature"` JsApiList []string `json:"jsApiList"` } func New(appId string, appSecret string, url string) Wxconfig { wx := Wxconfig{appId, appSecret, url} return wx } // GetWechatConfig 创建类方法获取jssdk配置项目 返回json串 func (wx Wxconfig) GetWechatConfig() signPackage { appid = wx.appId appsecret = wx.appSecret fmt.Printf("running appid: %s appsecret: %s\n", wx.appId, wx.appSecret) ticket := getJsApiTicket() timestamp := timestamp() fmt.Printf("timestamp%d", timestamp) nonceStr := getRandomString(16) fmt.Printf("nonceStr:%s", nonceStr) url := wx.url myString := fmt.Sprintf("jsapi_ticket=%s&noncestr=%s×tamp=%d&url=%s", ticket, nonceStr, timestamp, url) fmt.Printf("myString:%s", myString) signature := mySha1(myString) s := signPackage{wx.appId, nonceStr, timestamp, url, signature, []string{"onMenuShareTimeline", "onMenuShareAppMessage"}} //fmt.Println(signPackage) //data, err := json.Marshal(signPackage) //if err != nil { // fmt.Println(err) //} return s } // 函数首字母小写 表示私有 func getJsApiTicket() string { fmt.Printf("获取getJsApiTicket\n") // 获取ticket内容 jsonStr := readFile("ticket.txt") // 解析json串 j := json1{} err := json.Unmarshal([]byte(jsonStr), &j) if err != nil { fmt.Println(err.Error()) return "" } expireTime := j.Expire_time jsapiTicket := j.Jsapi_ticket if expireTime < timestamp() { // ticket过期需要从新获取 // 获取access_token生成ticket accessToken := getAccessToken() fmt.Println(accessToken) if accessToken == "" { return "" } url := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=%s", accessToken) resp, _ := http.Get(url) body, _ := ioutil.ReadAll(resp.Body) fmt.Println(string(body)) // 解析body ticket := ticket{} err := json.Unmarshal(body, &ticket) if err != nil { fmt.Println(err.Error()) return "" } if ticket.Errcode == 0 { jj := json1{timestamp() + 7000, ticket.Ticket} data, err := json.Marshal(jj) if err != nil { fmt.Println(err) } setFile(string(data), "ticket.txt") return ticket.Ticket } else { return "" } } return jsapiTicket } // 写文件"./jssdk/ticket.txt" func setFile(ticket string, filename string) bool { d1 := []byte(ticket) err := ioutil.WriteFile(filename, d1, 0644) if err != nil { fmt.Println(err) return false } return true } // 读取文件内容 func readFile(filename string) string { data, err := ioutil.ReadFile(filename) if err != nil { fmt.Println("文件读取出错", err) return fmt.Sprintf("%s", err) } fmt.Println("文件读取成功", string(data)) return string(data) } // 获取access token func getAccessToken() string { // 获取ticket内容 jsonStr := readFile("token.txt") // 解析json串 j := json2{} err := json.Unmarshal([]byte(jsonStr), &j) if err != nil { fmt.Println(err.Error()) return "" } expireTime := j.Expire_time accessToken := j.Access_token if expireTime < timestamp() { // 获取新token url := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", appid, appsecret) resp, _ := http.Get(url) body, _ := ioutil.ReadAll(resp.Body) fmt.Println(string(body)) // 解析body token := token{} err := json.Unmarshal([]byte(body), &token) if err != nil { fmt.Println(err.Error()) return "" } if len(token.Access_token) > 0 { jj := json2{timestamp() + 7000, token.Access_token} data, err := json.Marshal(jj) if err != nil { fmt.Println(err) } setFile(string(data), "token.txt") return token.Access_token } else { return "" } } return accessToken } func timestamp() int { timestamp := strconv.FormatInt(time.Now().UTC().Unix(), 10) myTimestamp, _ := strconv.Atoi(timestamp) return myTimestamp } // 获取随机字符串 func getRandomString(l int) string { str := "0123456789abcdefghijklmnopqrstuvwxyz" bytes := []byte(str) var result []byte r := rand.New(rand.NewSource(time.Now().UnixNano())) for i := 0; i < l; i++ { result = append(result, bytes[r.Intn(len(bytes))]) } return string(result) } // sha1加密 func mySha1(data string) string { t := sha1.New() _, err := io.WriteString(t, data) if err != nil { return "" } return fmt.Sprintf("%x", t.Sum(nil)) }
接口层
package main import ( "github.com/gin-gonic/gin" "go-jssdk/jssdk" ) func main() { r := gin.Default() r.Use(Cors()) // 主要是这里 r.GET("/jssdk", func(c *gin.Context) { url := c.DefaultQuery("url", "url") jssdk := jssdk.New("wx74xxxxxx80f5a445", "c2e72ee嘻嘻嘻嘻嘻嘻dc3dc594", url) config := jssdk.GetWechatConfig() c.JSON(200, gin.H{ "message": "ok", "data": config, }) }) r.Run(":52446") } // Cors 开启跨域函数 func Cors() gin.HandlerFunc { return func(c *gin.Context) { c.Writer.Header().Set("Access-Control-Allow-Origin", "*") c.Writer.Header().Set("Access-Control-Expose-Headers", "Access-Control-Allow-Origin") c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT") if c.Request.Method == "OPTIONS" { c.AbortWithStatus(204) return } defer func() { if err := recover(); err != nil { } }() c.Next() } }
前端代码
引用jssdk,操他妈的马化腾 张小龙,整了个什么啥逼玩意,狗屁玩意, 别用 1.6.0,别用 1.6.0,别用 1.6.0,别用 1.6.0
<script src="http://res2.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
function share(article) { let url = location.href.split("#")[0]; axios .get("http://微信狗东西去死:52446/jssdk?url=" + encodeURIComponent(url)) .then(function (response) { let msg = response.data.data; wx.config({ debug: false, appId: msg.appId, timestamp: msg.timestamp, nonceStr: msg.nonceStr, signature: msg.signature, jsApiList: [ "updateAppMessageShareData", "updateTimelineShareData", "onMenuShareAppMessage", "onMenuShareTimeline", "onMenuShareQQ", "onMenuShareQZone", ], }); //处理验证失败的信息 wx.error(function (res) { console.log("res", res); }); wx.ready(function () { wx.onMenuShareAppMessage({ title: article.title, desc: article.intro ? article.intro : "", link: url, imgUrl: "http://img.谢谢谢谢谢.com/2021/01/22/张小龙全家死光.jpg", }); wx.onMenuShareTimeline({ title: article.title, desc: article.intro ? article.intro : "", link: url, imgUrl: "http://img.谢谢谢谢谢.com/2021/01/22/一天操一遍马化腾奶奶.jpg", }); }); }); }