看到网上没有相关的完整文章,于是自己记录一下
1. 微信小程序请求后端获取session_key并存储到storageSync()
wx.login()获取code,携带code请求后端,后端调用 auth.code2Session,使用 code 换取 session_key 信息。
然后存储到微信小程序本地或存储到服务端,我这里为了方便存在了本地。
2. 微信小程序获取步数
wx.getWeRunData({
success:(res) => {
//得到步数数据,包括encryptedData与iv
this.decryptedData(res.encryptedData, res.iv);
}
})
3. 请求后端解析加密数据
decryptedData(encryptedData, iv) {
let SessionKey = wx.getStorageSync("session_key")
let data = {
EncryptedData: encryptedData,
Iv: iv,
SessionKey,
}
//携带data请求后端相应的接口,代码已省略
········
tokenRequest({url, data, header, method}).then(res=>{
if(res.data.code==0) {
this.setData({
step: res.data.data.step,
})
}
})
},
4. 后端解码
type WeRunCryptDataInput struct {
EncryptedData string `json:"encryptedData" note:""`
Iv string `json:"iv" note:""`
SessionKey string `json:"sessionKey" note:""`
}
type WeRunData struct {
TimeStamp uint64 `json:"timestamp" note:"时间"`
Step uint64 `json:"step" note:"步数"`
}
type WeRunDataList struct {
StepInfoList []*WeRunData `json:"stepInfoList"`
}
func (s *Data) DecryptWeRunData(argument WeRunCryptDataInput) (WeRunData, business.Error) {
//解码
aesKey, err := base64.StdEncoding.DecodeString(argument.SessionKey)
if err != nil {
return nil, business.NewError(errors.InternalError, err)
}
cipherText, err := base64.StdEncoding.DecodeString(argument.EncryptedData)
if err != nil {
return nil, business.NewError(errors.InternalError, err)
}
ivBytes, err := base64.StdEncoding.DecodeString(argument.Iv)
if err != nil {
return nil, business.NewError(errors.InternalError, err)
}
block, err := aes.NewCipher(aesKey)
if err != nil {
return nil, business.NewError(errors.InternalError, err)
}
mode := cipher.NewCBCDecrypter(block, ivBytes)
mode.CryptBlocks(cipherText, cipherText)
cipherText, err = pkcs7Unpad(cipherText, block.BlockSize())
if err != nil {
return nil, business.NewError(errors.InternalError, err)
}
result := &WeRunDataList{}
err = json.Unmarshal(cipherText, &result)
if err != nil {
return nil, business.NewError(errors.InternalError, err)
}
// do something else,例如存储数据
···
//代码已省略
return result.StepInfoList[30], nil
}
// pkcs7Unpad returns slice of the original data without padding
func pkcs7Unpad(data []byte, blockSize int) ([]byte, error) {
if blockSize <= 0 {
return nil, fmt.Errorf("invalid block size")
}
if len(data)%blockSize != 0 || len(data) == 0 {
return nil, fmt.Errorf("invalid PKCS7 data")
}
c := data[len(data)-1]
n := int(c)
if n == 0 || n > len(data) {
return nil, fmt.Errorf("invalid padding on input")
}
for i := 0; i < n; i++ {
if data[len(data)-n+i] != c {
return nil, fmt.Errorf("invalid padding on input")
}
}
return data[:len(data)-n], nil
}