微信小程序獲取手機號,golang實現第三方服務


微信小程序無法在前端直接獲取用戶的手機號,只能獲取到aes加密后的手機號信息和一個code。將加密后的手機信息和code傳到我們自己寫的服務就可以解密了。

解密需要兩個步驟:

1.使用code從微信API獲取session key。

直接使用以下參數,對api發起get請求

https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=APPSECRET&js_code=CODE&grant_type=authorization_code
   屬性 描述
appid
微信小程序的appid,從微信小程序平台獲取,每個小程序都不一樣
secret
微信小程序的app secret,從微信小程序平台獲取,每個小程序都不一樣
js_code
小程序前端獲取用戶手機號信息時的code
grant_type

 固定值 authorization_code

2.使用session key解密加密的手機信息。

 

go語言代碼示例

package main

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"

	"github.com/gin-gonic/gin"
)

type Reply struct {
	Code int         `json:"code"`
	Data interface{} `json:"data"`
}

func main() {

	gin.SetMode(gin.ReleaseMode)
	router := gin.Default() //實例化一個gin

	router.POST("/getnum", getNum)

	fmt.Println("服務啟動...端口為9300")
	router.Run("127.0.0.1:9300") //監聽9300端口
}

func getNum(c *gin.Context) {
	var req struct {
		EncryptedData string
		Iv            string
		Code          string
	}
	err := c.Bind(&req)
	if err != nil {
		c.Error(err)
	}
	url := "https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=" + req.Code + "&grant_type=authorization_code"
	resp, err := http.Get(url)
	if err != nil {
		c.Error(err)

	}
	defer resp.Body.Close()
	s, _ := ioutil.ReadAll(resp.Body)
	res := make(map[string]string)
	json.Unmarshal(s, &res)
	key, _ := base64.StdEncoding.DecodeString(res["session_key"])
	iv, _ := base64.StdEncoding.DecodeString(req.Iv)
	ciphertext, _ := base64.StdEncoding.DecodeString(req.EncryptedData)
	plaintext := make([]byte, len(ciphertext))

	block, err := aes.NewCipher(key)
	if err != nil {
		panic(err)
	}
	mode := cipher.NewCBCDecrypter(block, iv)
	mode.CryptBlocks(plaintext, ciphertext)

	plaintext = PKCS7UnPadding(plaintext)
	fmt.Println("return:", string(plaintext))
	c.JSON(http.StatusOK, Reply{http.StatusOK, string(plaintext)})
}

// 發送post請求
func post(url, data string) (string, error) {
	reader := bytes.NewReader([]byte(data))

	request, err := http.NewRequest("POST", url, reader)
	if err != nil {
		return "", err
	}
	defer request.Body.Close() //程序在使用完回復后必須關閉回復的主體
	request.Header.Set("Content-Type", "application/json;charset=UTF-8")
	//必須設定該參數,POST參數才能正常提交,意思是以json串提交數據

	client := http.Client{}
	resp, err := client.Do(request) //Do 方法發送請求,返回 HTTP 回復
	if err != nil {
		return "", err
	}

	respBytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}
	return string(respBytes), nil
}

func PKCS7Padding(ciphertext []byte) []byte {
	padding := aes.BlockSize - len(ciphertext)%aes.BlockSize
	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(ciphertext, padtext...)
}

func PKCS7UnPadding(plantText []byte) []byte {
	length := len(plantText)
	unpadding := int(plantText[length-1])
	return plantText[:(length - unpadding)]
}

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM