小程序获取手机号码的过程

一、通过按钮发起授权请求

ScreenShot_2025-12-15_162017_186

“允许”之后,得到:
  code: '',          // 登录code
  encryptedData: '', // 加密数据
  iv: '',            // 初始向量
  cloudID: '',       // 云开发ID(可选)

二、这数据发送到后端,对手机号码进行解密

后端解密后得到openId,手机号码,根据这信息进行业务处理:

// 例如:
// 1. 根据openId查找用户
// 2. 如果不存在则创建新用户
// 3. 更新用户手机号等信息
// 4. 返回用户实体

常见问题和注意事项

Q1:为什么需要code?

A: 后端需要通过 code 调用微信接口换取 session_key,然后用 session_key 解密手机号。

Q2:获取手机号需要什么条件?

小程序已认证(非个人主体)
需要先在微信公众平台开通手机号授权
用户必须是已授权登录的用户

Q3:获取失败的可能原因

code过期:code有效期5分钟,获取后应立即使用
session_key不一致:确保解密用的session_key与加密时的匹配
权限问题:小程序没有手机号获取权限

安全注意事项

不要在前端解密:解密必须在后端进行,避免暴露session_key
及时更新session_key:微信可能会刷新session_key
验证返回数据:解密后验证数据格式和有效性
这样的设计是微信出于用户隐私安全考虑,确保手机号等敏感信息只在安全的环境下解密。

小程序相关部分代码

<button v-if="!hasUserInfo" open-type="getUserInfo" @getuserinfo="onGetUserInfo" lang="zh_CN" >授权登录</button>

// 手机号授权回调
async onGetPhoneNumber(e) {
  if (e.detail.errMsg === 'getPhoneNumber:ok') {
    this.isLoggingIn = true;

    // 获取到加密数据
    this.encryptedData = e.detail.encryptedData;
    this.iv           = e.detail.iv;
    this.cloudID      = e.detail.cloudID;

    // 调用后端接口解密手机号并登录
    await this.wxPhoneLogin();
  } else {
    uni.showToast({
      title: '获取手机号失败',
      icon: 'none'
    });
  }
}

// 微信手机号登录
async wxPhoneLogin() {
  try {
    const params = {
      code:        this.code,
      encryptedData: this.encryptedData,
      iv:          this.iv,
      cloudID:     this.cloudID,
      platform:    'weixin'
    };

    const res = await this.$http.request({
      method: 'post',
      url:    '/api/user/wxlogin',
      data:   params
    });

    if (res.status) {
      const userInfo = {
        token:    res.data.token,
        user_id:  res.data.userId,
        username: res.data.userName,
        phone:    res.data.phone
      };

      uni.setStorageSync('USER_INFO', userInfo);
      uni.setStorageSync('PHONE', res.data.phone);

      uni.switchTab({ url: '/pages/index/index' });
      uni.showToast({
        title: '登录成功!',
        icon:  'success'
      });
    } else {
      uni.showModal({
        title:      '错误',
        content:    res.message || '登录失败',
        showCancel: false
      });
    }
  } catch (error) {
    console.error('微信登录请求错误:', error);
    uni.showModal({
      title:      '错误',
      content:    error.message || '请求失败',
      showCancel: false
    });
  } finally {
    this.isLoggingIn = false;
  }
}
posted @ 2025-12-15 16:32  Tlink  阅读(10)  评论(0)    收藏  举报