小程序原生授权手机号

前端注意,这里一定是直接获取的code。这里的code很容易混淆哦。

一定是getPhoneNumber的

复制代码
 getPhoneNumber(e) {
    // 1. 防止重复点击
    if (this.data.isGettingPhone) return;

    // 2. 检查用户是否授权
    if (e.detail.errMsg !== 'getPhoneNumber:ok') {
      wx.showToast({ title: '授权失败', icon: 'none' });
      return;
    }

    // 3. 设置加载状态
    this.setData({ isGettingPhone: true });

    const encryptedData = e.detail.encryptedData;
    const iv = e.detail.iv;
    const user_id = this.data.userInfo.user_id;

    const phoneCode = e.detail.code;

    // 5. 立即发送请求(不要延迟)
    App._post_form('user/getphone', {
      encryptedData: encryptedData,
      iv: iv,
      code: phoneCode,     // ← 全新 code
      user_id: user_id
    }, (result) => {
      this.setData({ isGettingPhone: false });
      if (result.code === 1) {
        wx.showToast({ title: '绑定成功', icon: 'success' });
        this.setData({
          hasPhone: true,
          PhoneNumber: result.data.phoneNumber
        });
      } else {
        wx.showToast({ title: result.msg || '操作失败', icon: 'none' });
      }
    }, () => {
      // 请求失败回调
      this.setData({ isGettingPhone: false });
      wx.showToast({ title: '网络错误', icon: 'none' });
    });
  },

data里加:isGettingPhone: false,

前端:

复制代码
<button
      class="phone-btn {{hasPhone ? 'btn-success' : ''}}"
      open-type="getPhoneNumber"
      bindgetphonenumber="getPhoneNumber"
      loading="{{isGettingPhone}}"
    >
      {{ hasPhone ? '已授权' : '点击授权手机号' }}
    </button>

public function getphone()
    {
        $data = $this->request->param();

        $code = $data['code'] ?? null;
        $user_id = $data['user_id'] ?? null;

        if (!$code || !$user_id) {
            return $this->renderError('参数缺失');
        }

        // 1. 获取小程序配置
        $wxapp_id = (string) input('wxapp_id', '');
        $wxConfig = Db::name('wxapp')->where('wxapp_id', $wxapp_id)->find();
        if (!$wxConfig) {
            return $this->renderError('小程序配置不存在');
        }
        $params = [
            'appid' => $wxConfig['app_id'],
            'secret' => $wxConfig['app_secret'],
            'grant_type' => 'client_credential'
        ];
        $tokenUrl = 'https://api.weixin.qq.com/cgi-bin/token?' . http_build_query($params);

        // 3. 发送 GET 请求
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $tokenUrl);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        $tokenRes = json_decode($response, true);

        // 4. 严格校验响应
        if ($httpCode !== 200 || !isset($tokenRes['access_token']) || !is_string($tokenRes['access_token'])) {
            return $this->renderError('服务初始化失败');
        }

        $accessToken = $tokenRes['access_token'];
        $headers = [
            'Content-Type: application/json; charset=utf-8',
            'Accept: application/json'
        ];

        $url = 'https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=' . $accessToken;

        $requestBody = json_encode(['code' => $code], JSON_UNESCAPED_UNICODE);

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        $response = curl_exec($ch);
        curl_close($ch);
        $phoneRes = json_decode($response, true);
        // 4. 处理结果
        if (!is_array($phoneRes)) {
            return $this->renderError('接口返回格式错误');
        }

        // 5. 成功拿到手机号
        $phoneNumber = $phoneRes['phone_info']['phoneNumber'] ?? '';

        if (!$phoneNumber) {
            return $this->renderError('未返回手机号');
        }

        // 6. 保存到数据库
        $model = new UserModel;
        if (!$model->editPhone($user_id, $phoneNumber)) {
            return $this->renderError($model->getError() ?: '保存失败');
        }

        return $this->renderSuccess('操作成功', ['phoneNumber' => $phoneNumber]);
    }
相关推荐
白帽攻防录2 小时前
SRC 挖洞:Apache APISIX 非规范路径授权绕过深度复盘,CVE-2026-94269 怎么绕过网关访问后端
网络安全·apache·src漏洞挖掘
andrsted2 小时前
练题簿在线免费刷题:选择、填空、简答与排序,多种题型练出不同的掌握程度
学习·微信小程序·小程序·学习方法·刷题
长沙三为智能科技11 小时前
家政小程序门店运营模块设计:会员、下单、派单、结算四段链路的落地拆解
python·小程序·内容运营
weixin_1772972206912 小时前
回收小程序做自营还是撮合?先看你手里有什么
小程序
Knight_AL13 小时前
从 EasyExcel 到 Apache Fesod:Java Excel 处理生态的一次重构
java·apache·excel
andrsted13 小时前
练题簿在线免费刷题:Word、PDF 导题与预览补全,把现成资料变成可练习题库
微信小程序·小程序·pdf·word·学习方法·刷题
AI行业应用研究13 小时前
会务信息载体的演进:纸质、PDF 与结构化数据源的分发成本与版本一致性
大数据·人工智能·安全·小程序·架构·pdf
Geek_Vison13 小时前
保险APP已经用了Flutter,还能接入小程序吗?
flutter·小程序·uni-app·mpaas·小程序容器
FX1317887KP_1 天前
从KET到PET口语进阶:词汇量翻倍后,口语如何跟上?
小程序·ket口语·pet口语·fce备考·剑桥英语
m0_587383001 天前
工业场景设备维修维护实战技巧 全流程标准化落地与常见问题排查指南
java·spring·小程序·架构·需求分析