评论

云函数获取用户手机号吗?

云函数获取手机号码,用云函数自己搭建后台。

小程序通过云函数获得用户手机号码?

思路解析,

了解了小程序的加密方式,我们就可以自己去解密我们需要的信息。如:最困住我们的用户手机号码?
官方是有案例的,想更多学习可以给与参考,但是估计要多看几遍,有node基础的就比较好理解一些。

下面是官网地址:

https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html#method-cloud

下面开始说我自己的方法;

1.首先构建云函数,需要两个云函数,一个用来解密,session_key,一个用来解密加密手机号码;

//云函数:getSession;
// 云函数入口文件

const cloud = require('wx-server-sdk')

//npm   install  request-promise  通过终端下载npm install wx-server-sdk ,
const rp = require('request-promise');

cloud.init()

// 云函数入口函数

exports.main = async (event, context) => {
  const _JSCODE = event.code
  const AccessToken_options = {

method: 'GET',

url: 'https://api.weixin.qq.com/sns/jscode2session',

qs: {

  appid: '',  //你的小程序appid;

  secret: '',  //你的秘钥

  grant_type: 'authorization_code',

  js_code: _JSCODE

},

json: true



  };


  const resultValue = await rp(AccessToken_options);

  return { resultValue }
}

下载好需要的两个包,就可以对云函数初始化,执行npm init
有个起名字的环节,用过node的都知道,默认index.js,有个选择

package name: (gettoken) index.js
version: (1.0.0)
description:
git repository:
keywords:
author:
license: (ISC)
About to write to D:\projects\zy_face_id_wxs\server\getToken\package.json:

{
  "name": "index.js",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
"request-promise": "^4.2.4",
"wx-server-sdk": "^0.8.1"
  },
  "devDependencies": {},
  "description": ""
}


Is this OK? (yes) yes

这是初始化,终端的代码;

右键点击上传并部署到云端;

下面是客户端的代码;

  getPhoneNumber(e) {
if (!e.detail.errMsg || e.detail.errMsg != "getPhoneNumber:ok") {
wx.showModal({
  content: '不能获取手机号码',
  showCancel: false
})
return;
  }
  wx.showLoading({
title: '获取手机号中...',
  })
console.log(e)
wx.login({
  success(res) {
if (res.code) {
  console.log(res.code)
  console.log(e.detail.iv)
  console.log(e.detail.encryptedData)
  wx.cloud.callFunction({
name: 'getSession',  //调用云函数获取session_key;
data: {
  code: res.code,
},
success: res => {
  wx.hideLoading()
  // console.log(res.result.resultValue)
  var data = res.result.resultValue
  console.log(data)
  console.log(data.session_key)   //获取到了session_key的值;
},
fail: error => {
  console.log(error)
}
  })
}
  }
})
  },

2.构建第二个云函数 GetWX;

// 云函数入口文件
const cloud = require('wx-server-sdk')
// const requestpromise = require('request-promise');

var WXBizDataCrypt = require('./RdWXBizDataCrypt') // 用于手机号解密
cloud.init()

exports.main = async (event, context) => {
  const session_key = event.session_key
  //appid写入你自己的appid,session_key 用第一个云函数的返回值;
  const pc = new WXBizDataCrypt(appid, session_key )  // -解密第一步
  const data = pc.decryptData(event.encryptedData, event.iv)   // 解密第二步
  return {
  data
  }
}

这个同样执行上面的步骤,npm install wx-server-sdk 和初始化npm init;
重点来了,解密所需要的js文件。

`

这两个文件已经上传到我的网盘里面,需要的请下载;

  1. https://pan.baidu.com/s/1VrS1gX_Bw3dKaZkQnNzy2A
  2. 提取码:cxnh;
  3. 格式和图片的保持一致,并上传到云端。

3.开始前端调用了;

代码如下;

getPhoneNumber(e) {
if (!e.detail.errMsg || e.detail.errMsg != "getPhoneNumber:ok") {
wx.showModal({
  content: '不能获取手机号码',
  showCancel: false
})
return;
  }
  wx.showLoading({
title: '获取手机号中...',
  })
console.log(e)
wx.login({
  success(res) {
if (res.code) {
  console.log(res.code)
  console.log(e.detail.iv)
  console.log(e.detail.encryptedData)
  wx.cloud.callFunction({
name: 'getSession',  //调用云函数获取session_key;
data: {
  code: res.code,
},
success: res => {
  wx.hideLoading()
  var data = res.result.resultValue
  console.log(data)
  console.log(data.session_key)   //获取到了session_key的值;
  const session_key=data.session_key
  wx.cloud.callFunction({
name:'getWX',  //解析秘文,获得手机号码;
data:{
  session_key: session_key,
  encryptedData: e.detail.encryptedData,
  iv: e.detail.iv,
},
success:res=>{
  console.log(res)
},
fail:err=>{
  console.log(err)
}

  })
},
fail: error => {
  console.log(error)
}
  })
}
  }
})
  },

4.输出的结果:

遇到问题了在私信问我,一一回答。

最后一次编辑于  07-17  
点赞 2
收藏
评论

8 个评论

  • ZhaoJH
    ZhaoJH
    07-17

    牛逼

    07-17
    赞同 2
    回复 1
    • 心有灵犀
      心有灵犀
      07-24
      还好还好了
      07-24
      回复
  • 心有灵犀
    心有灵犀
    10-10

      onShow: function () {

        wx.clearStorageSync('session_key')

        wx.login({ //换取code值,

        success(res) {

        if (res.code) {

        wx.cloud.callFunction({

        name: 'GetSessions', //调用云函数获取session_key;

        data: {

        code: res.code,

        },

        success: res => {

        var data = res.result.resultValue

        console.log(data)

        wx.setStorage({

        key: "session_key",

        data: {

        session_key: data.session_key,

        open_id: data.openid

        }

        }) 

        }

        })

        }

        }

        }) 

        

        },

    先获取code,从而换取session_key,避免出现官方提示的错误。


    10-10
    赞同
    回复
  • 挖机报价
    挖机报价
    10-01

    普通个人开发者可以用这个么?

    10-01
    赞同
    回复 1
    • 心有灵犀
      心有灵犀
      10-10
      可以使用的。
      10-10
      回复
  • 南京长宁欣
    南京长宁欣
    09-22


    09-22
    赞同
    回复 2
    • 南京长宁欣
      南京长宁欣
      09-22
      删除云函数,重新构建,解决了。又出现:Cannot read property 'session_key' of undefined;at api cloud.callFunction success callback function TypeError: Cannot read property 'session_key' of undefined。
      09-22
      1
      回复
    • 心有灵犀
      心有灵犀
      10-10回复南京长宁欣
      你的传值出问题,看下你是否取得'session_key'的值,后端云函数是不是接收到这个参数。
      10-10
      回复
  • 南京长宁欣
    南京长宁欣
    09-22

    楼主您好!复制您的方法,为啥出现这个提示,请指教!

    Error: errCode: -404011 cloud function execution error | errMsg: cloud.callFunction:fail requestID c970bc35-dcd8-11e9-9e4e-525400681fe1, cloud function service error code -504002, error message Cannot find module 'request-promise'; at cloud.callFunction api;

    09-22
    赞同
    回复
  • 「©」
    「©」
    08-02

    {"errorCode":1,"errorMessage":"user code exception caught","stackTrace":"First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object."}


    会出现这个错误是啥回事?

    08-02
    赞同
    回复 6
    • 心有灵犀
      心有灵犀
      08-02
      你是调用的云函数吗?方便的话,看下你的代码..
      08-02
      回复
    • 「©」
      「©」
      08-02回复心有灵犀

      index.js

      // 云函数入口文件
      const cloud = require('wx-server-sdk')
       
      var WXBizDataCrypt = require('./WXBizDataCrypt')
       
      const requestSync = require('./requestSync')
       
      cloud.init({
        env: 'xxxx',
        traceUser: true
      })
       
      // 云函数入口函数
      exports.main = async (event, context) => {
       
       
        var appId = cloud.getWXContext().APPID
        var code = event.code
        var encryptedData = event.encryptedData
        var iv = event.iv
        const secret = 'xxxxxxxxxxxxxxx'
        const url = {
          url: 'https://api.weixin.qq.com/sns/jscode2session?appid=' + appId + '&secret=' + secret + '&js_code=' + code + '&grant_type=authorization_code'
        }
        const req = await requestSync(url);
        const session = JSON.parse(req);
        const sessionKey = session.session_key;
       
        var pc = new WXBizDataCrypt(appId, sessionKey)
        var data = pc.decryptData(encryptedData, iv)
        console.log("data = ", data)
        return data
       
      }


      WXBizDataCrypt.js

      var crypto = require('crypto')
       
      function WXBizDataCrypt(appId, sessionKey) {
        this.appId = appId
        this.sessionKey = sessionKey
      }
       
      WXBizDataCrypt.prototype.decryptData = function (encryptedData, iv) {
        // base64 decode
        console.log("errr1")
        var sessionKey = new Buffer(this.sessionKey, 'base64')
        console.log("errr2")
        encryptedData = new Buffer(encryptedData, 'base64')
        console.log("errr3")
        var iv = new Buffer(iv, 'base64')
         
        try {
           
           // 解密
          var decipher = crypto.createDecipheriv('aes-128-cbc', sessionKey, iv)
          // 设置自动 padding 为 true,删除填充补位
          decipher.setAutoPadding(true)
          var decoded = decipher.update(encryptedData, 'binary', 'utf8')
          decoded += decipher.final('utf8')
          console.log("errr4")
          decoded = JSON.parse(decoded)
       
        } catch (err) {
          throw new Error('Illegal Buffer 1')
        }
       
        if (decoded.watermark.appid !== this.appId) {
          throw new Error('Illegal Buffer 2')
        }
       
        return decoded
      }
       
      module.exports = WXBizDataCrypt


      08-02
      回复
    • 「©」
      「©」
      08-02回复心有灵犀

      之前都一直正常运行的。

      08-02
      回复
    • 心有灵犀
      心有灵犀
      08-02回复「©」
      cloud.init({ env: 'xxxx', traceUser: true })你这里是什么情况?这个情况我没遇到过,是云函数调用出了问题,你在云端测试一下,看看有没有返回值。然后在试试。。。还有看一下的onLoad: function (options) { wx.cloud.init({ env: 'zyfaceid-6da0cb' }) },云环境的Id是不是和现在用的环境相同。
      08-02
      回复
    • 「©」
      「©」
      08-02回复心有灵犀

      打印到一个错误,

      {"errcode":40125,"errmsg":"invalid appsecret, view more at http:\/\/t.cn\/RAEkdVq, hints: [ req_id:  ]"}


      invalid appsecret是什么?

      08-02
      回复
    查看更多(1)
  • 柠檬茶
    柠檬茶
    07-24

    获取个手机号需要这么多js吗


    07-24
    赞同
    回复 1
    • 心有灵犀
      心有灵犀
      07-24
      除去console.log(),js不多,只是怕错,输出的比较多,关键还是云函数,就只自己写的后端。
      07-24
      回复
  • p
    p
    07-18

    正需要这个功能, 我试试

    07-18
    赞同
    回复 1
    • 心有灵犀
      心有灵犀
      07-19
      好的,有啥问题可以再问我。
      07-19
      回复