微信小程序-获取用户手机号

uniapp 提供了获取手机号的 button 组件:

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

uniapp 提供了新旧两种版本的接口:

接口类型前端返回参数后端解密方式适用场景
旧版接口encryptedDataiv使用 session_key 解密兼容低版本微信客户端
新版接口动态 code直接调用微信接口换取手机号仅需支持微信 7.0.0+ 版本

动态令牌 code 与登录 code 的区别:

  • 登录 code:通过 wx.login() 获取,用于换取 session_key
  • 动态令牌 code:通过 wx.getPhoneNumber() 返回(旧版接口返回 encryptedData,新版返回动态 code)。

下面我们来分别看一下👇

旧版接口

前端:调用 uni.getPhoneNumber 获取加密手机号数据(encryptedData 和 iv),并将 uni.login 生成的 code 发送给后端,以便后端生成 session_key 用来解密。

后端:使用 session_key、encryptedData 和 iv 解密获取真实手机号。

前端-核心代码:

getPhoneNumber(e) { // 底部弹起用户手机号授权弹窗
    if (e.detail.errMsg == 'getPhoneNumber:ok') {
      const encryptedData = e.detail.encryptedData;
      const iv = e.detail.iv;

      // 优先使用之前保存的code
      const code = this.data.code || '';
      
      // 如果没有有效的code,则重新调用login获取
      if (!code) {
        wx.login({
          success: (loginRes) => {
            // 调用后端手机号解密接口,将 encryptedData、iv、code 发送到后端解密获取手机号
            api.decryptPhone({ encryptedData, iv, code })
          }
        });
      } else {
        api.decryptPhone({ encryptedData, iv, code })
      }

      

    } else {
      // 用户拒绝授权
      console.log('用户拒绝授权获取手机号');
    }
}

新版接口


前端:点击按钮生成动态 code,传给后端;

后端:直接用此 code 调用微信接口 phonenumber.getPhoneNumber 换取手机号(无需 session_key 解密,微信服务器直接返回明文手机号)。

前端-核心代码:

    getPhoneNumber(e) {
        const code = e.detail.code;
        if (code) {
            // 调用后端获取手机号接口,传入动态code即可
            api.getPhone({ code });
        }
    }

    【附录】---------------------------------------

    (旧版)前端完整代码:

    // 1. 先检查session_key是否有效
    wx.checkSession({
      success() {
        // session_key有效,直接获取手机号
        getPhoneNumber();
      },
      fail() {
        // session_key已过期,重新登录获取code
        wx.login({
          success: function(res) {
            if (res.code) {
              // 保存新的code,后续用于获取session_key
              const code = res.code;
              getPhoneNumber(code);
            }
          }
        });
      }
    });
    
    // 2. 获取手机号的函数
    function getPhoneNumber(existCode) {
      wx.getUserProfile({
        desc: '用于完善会员资料',
        success: function(userRes) {
          // 显示获取手机号的按钮
          wx.showModal({
            title: '提示',
            content: '需要获取您的手机号以完成注册',
            success: function(modalRes) {
              if (modalRes.confirm) {
                // 点击确定,显示获取手机号按钮
                wx.navigateTo({
                  url: '/pages/bindPhone/bindPhone'
                });
              }
            }
          });
        }
      });
    }
    
    
    // 3. 在绑定手机号页面的js中
    onGetPhoneNumber: function(e) {
        if (e.detail.errMsg === 'getPhoneNumber:ok') {
          const encryptedData = e.detail.encryptedData;
          const iv = e.detail.iv;
          
          // 优先使用之前保存的code
          const code = this.data.code || '';
          
          // 如果没有有效的code,则重新调用login获取
          if (!code) {
            wx.login({
              success: (loginRes) => {
                this.sendPhoneData(loginRes.code, encryptedData, iv);
              }
            });
          } else {
            this.sendPhoneData(code, encryptedData, iv);
          }
        } else {
          wx.showToast({
            title: '授权失败',
            icon: 'none'
          });
        }
      },
      
      sendPhoneData: function(code, encryptedData, iv) {
        wx.request({
          url: 'https://your-server.com/api/decryptPhone',
          method: 'POST',
          data: {
            code: code,
            encryptedData: encryptedData,
            iv: iv
          },
          success: (res) => {
            if (res.data.success) {
              const phoneNumber = res.data.phoneNumber;
              // 处理手机号,如保存到本地或进行登录操作
              wx.setStorageSync('phoneNumber', phoneNumber);
              wx.showToast({
                title: '绑定成功',
                success: () => {
                  wx.navigateBack();
                }
              });
            } else {
              wx.showToast({
                title: res.data.message || '解密失败',
                icon: 'none'
              });
            }
          },
          fail: () => {
            wx.showToast({
              title: '网络错误',
              icon: 'none'
            });
          }
        });
      }   

    (新版)前端完整代码:

    onGetPhoneNumber(e) {
        if (e.detail.code) {
          // 获取到动态令牌code,发送到后端
          wx.request({
            url: 'https://your-server.com/api/getPhoneNumber',
            method: 'POST',
            data: {
              code: e.detail.code,
              // 可选:传递用户标识(如openid)
              openid: wx.getStorageSync('openid')
            },
            success: (res) => {
              if (res.data.success) {
                const phoneNumber = res.data.phoneNumber;
                wx.showToast({
                  title: `获取成功: ${phoneNumber}`,
                  icon: 'none'
                });
              } else {
                wx.showToast({
                  title: res.data.message || '获取失败',
                  icon: 'none'
                });
              }
            },
            fail: () => {
              wx.showToast({
                title: '网络错误',
                icon: 'none'
              });
            }
          });
        } else {
          wx.showToast({
            title: '用户拒绝授权',
            icon: 'none'
          });
        }
      }

    评论
    成就一亿技术人!
    拼手气红包6.0元
    还能输入1000个字符
     
    红包 添加红包
    表情包 插入表情
     条评论被折叠 查看
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值