uni-app在一键获取手机号时总是报错Error: Illegal Buffer,找不到问题所在

发布于 1周前 作者 vueper 来自 Uni-App

uni-app在一键获取手机号时总是报错Error: Illegal Buffer,找不到问题所在

错误信息

nodejs版本解密手机号报错?查阅不少资料已经按照不少答案改了一下午还是不对。前几天在微信交流社区提问也没有一个正解
重新修改了很多次代码,但是还是解密的时候报错。

以下是我的进入页面的onLoad,这是使用了login获取到了code在到云函数中获取sessionKey。
onLoad() {  
    let _this = this  
    uni.login({  
        success(res) {  
            if (res.code) {  
                uniCloud.callFunction({  
                    name: 'sys_getSessionKey',  
                    data: {js_code: res.code},  
                    success(res) {  
                        this.session_key = res.result.session_key  
                    }  
                })  
            }  
        }  
    })  
},
在云函数sys_getSessionKey通过js_code、appId、appSecret已经获取到了sessionKey。
然后在获取手机号的时候button上@getphonenumber="toGetPhone"

下面是在toGetPhone方法:
toGetPhone(e) {  
    let _this = this  
    if (e.detail.errMsg == "getPhoneNumber:fail user deny") {  
        return uni.$u.toast('您已经取消授权')  
    } else {  
        uniCloud.callFunction({  
            name: 'gr_quickLogin',  
            data: {  
                code: e.detail.code,  
                encryptedData: e.detail.encryptedData,  
                iv: e.detail.iv,  
                sessionKey: _this.session_key  
            },  
            success(res) {  
                console.log(res)  
            }  
        })  
    }  
},
就是在gr_quickLogin云函数中报错:Error: Illegal Buffer
以下是gr_quickLogin云函数内容:
'use strict';  
exports.main = async (event, context) => {  
    const WXBizDataCrypt = require('./WXBizDataCrypt.js')  
    var appId = "wx**************54"  
    var sessionKey = event.sessionKey  
    var encryptedData = event.encryptedData  
    var iv = event.iv  
    var pc = new WXBizDataCrypt(appId, sessionKey)  
    var data = pc.decryptData(encryptedData , iv)  
    console.log('解密后 data: ', data)  
    //返回数据给客户端  
    return data  
};
其中WXBizDataCrypt.js使用的是官方提供的js。

最后付上一个报错信息:
17:00:34.307 [本地调试]Error: Illegal Buffer  
17:00:34.308 [本地调试]    at global.__tempModuleExports.WXBizDataCrypt.decryptData (/Users/mengxiandong/Documents/HBuilderProjects/gr_ski/uniCloud-alipay/cloudfunctions/gr_quickLogin/WXBizDataCrypt.js:25:11)  
17:00:34.308 [本地调试]    at global.__tempModuleExports.exports.main (/Users/mengxiandong/Documents/HBuilderProjects/gr_ski/uniCloud-alipay/cloudfunctions/gr_quickLogin/index.js:9:16)  
17:00:34.308 [本地调试]    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
实在不知道为啥了,已经翻页了一下午的文档,看了各种案例。(前提是之前用java的后端没问题,最近想做迁移到uniapp云开发上,这块一直报错不知道为啥)

1 回复

在uni-app中处理一键获取手机号功能时遇到“Error: Illegal Buffer”错误,通常与数据处理或编码方式有关。这个功能一般依赖于小程序的原生接口,比如微信小程序的 wx.loginwx.getPhoneNumber。下面是一个基本的代码示例,用于展示如何在uni-app中正确处理一键获取手机号的功能,并附带一些可能的错误处理机制。

步骤 1: 配置小程序后台

确保已在微信小程序后台配置了“获取用户手机号”的接口权限,并生成了服务器端的解密密钥。

步骤 2: 前端代码

在uni-app的页面中,添加一个按钮用于触发获取手机号操作,并处理返回的加密数据。

<template>
  <view>
    <button open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">获取手机号</button>
  </view>
</template>

<script>
export default {
  methods: {
    getPhoneNumber(e) {
      if (e.detail.errMsg === "getPhoneNumber:ok") {
        // 获取到加密数据
        const encryptedData = e.detail.encryptedData;
        const iv = e.detail.iv;

        // 发送到服务器进行解密
        uni.request({
          url: 'https://yourserver.com/decryptPhoneNumber', // 替换为你的服务器地址
          method: 'POST',
          data: {
            encryptedData: encryptedData,
            iv: iv,
            // 通常还需要传递用户的session_key,这里假设已经通过wx.login获取并存储
            sessionKey: uni.getStorageSync('session_key') || ''
          },
          success: (res) => {
            console.log('解密后的手机号:', res.data.phoneNumber);
          },
          fail: (err) => {
            console.error('请求失败:', err);
          }
        });
      } else {
        console.error('获取手机号失败:', e.detail.errMsg);
      }
    }
  }
}
</script>

步骤 3: 后端代码(Node.js示例)

后端需要使用微信提供的解密算法来解密手机号。以下是一个简单的Node.js示例,使用crypto模块进行解密。

const crypto = require('crypto');

function decryptPhoneNumber(encryptedData, iv, sessionKey) {
  const sessionKeyBuffer = Buffer.from(sessionKey, 'base64');
  const encryptedDataBuffer = Buffer.from(encryptedData, 'base64');
  const ivBuffer = Buffer.from(iv, 'base64');

  const decipher = crypto.createDecipher('aes-128-cbc', sessionKeyBuffer);
  decipher.setAutoPadding(true);
  decipher.update(encryptedDataBuffer, null, 'binary');
  const decrypted = decipher.final('utf8');

  const decryptedObj = JSON.parse(decrypted);
  return decryptedObj.phoneNumber;
}

// 在你的服务器端处理POST请求时调用这个函数

注意,这里的代码示例假设你已经有了session_key,这通常是通过wx.login获得的临时登录凭证向微信服务器换取得到的。确保在调用getPhoneNumber接口前已经获取并存储了session_key

如果问题仍然存在,请检查加密数据的传递、服务器端的解密逻辑以及任何可能的字符编码问题。

回到顶部