微信小程序(6)获取微信用户绑定的手机号

 

获取手机号

  获取微信用户绑定的手机号,需先调用wx.login接口。

  因为需要用户主动触发才能发起获取手机号接口,所以该功能不由 API 来调用,需用 <button> 组件的点击来触发。

  注意:目前该接口针对非个人开发者,且完成了认证的小程序开放(不包含海外主体)。需谨慎使用,若用户举报较多或被发现在不必要场景下使用,微信有权永久回收该小程序的该接口权限。

使用方法

  需要将 <button> 组件 open-type 的值设置为 getPhoneNumber,当用户点击并同意之后,可以通过 bindgetphonenumber 事件回调获取到微信服务器返回的加密数据, 然后在第三方服务端结合 session_key 以及 app_id 进行解密获取手机号。

注意

  在回调中调用 wx.login 登录,可能会刷新登录态。此时服务器使用 code 换取的 sessionKey 不是加密时使用的 sessionKey,导致解密失败。建议开发者提前进行 login;或者在回调中先使用 checkSession 进行登录态检查,避免 login 刷新登录态。

 

小程序代码

<!--index.wxml-->
<view class="container">
  <view>
    <button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">获取手机号</button>
  </view>
</view>
//index.js
//获取应用实例
const app = getApp()

Page({
  data: {
    
  },
  onLoad: function () {
    
  },
 // 获取手机号
  getPhoneNumber(e){
    wx.login({
      success: function (res) {
        if (res.code) {
          //TODO
          console.log('获取code成功:' + JSON.stringify(res.code));
          console.log(res)
          app.globalData.code = res.code;
        } else {
          console.log('获取用户登录态失败!' + res.errMsg)
        }
      }
    });
    wx.request({
      url: 'http://demo.tp5.com/gatewayapp/wechat/getPhone', 
      data: { 'encryptedData': e.detail.encryptedData, 'iv': e.detail.iv, code: app.globalData.code},
      method: 'POST', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
      header: {
        'content-type': 'application/json'
      },// 设置请求的 header
      success: function (res) {
        console.log(res.data)
      },
      fail: function (err) {
        console.log(err);
      },
      complete: function () {
        // complete
      }
    })
  }
})

 

服务端代码( 这里将小程序的解密及错误代码集中在了一个文件中 )

开放数据校验与解密:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html

官方实例下载:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/demo/aes-sample.zip

<?php
namespace app\gatewayapp\controller;
use think\Controller;

class Wechat extends Controller {    
    private $appid = '小程序appid';
    private $AppSecret = '小程序AppSecret';
    private $sessionKey;    // 小程序session_key
    //'https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code'
    // code2Session 请求地址
    private $code2Session_url = 'https://api.weixin.qq.com/sns/jscode2session?appid=';

    // 小程序错误代码
    public static $OK = 0;
    public static $IllegalAesKey = -41001;
    public static $IllegalIv = -41002;
    public static $IllegalBuffer = -41003;
    public static $DecodeBase64Error = -41004;

    // 获取手机号
    public function getPhone(){

        // 拼接 code2Session 的 URL 地址, 获取用户 session_key 和 openid
        $url = $this->code2Session_url . $this->appid . '&secret=' . $this->AppSecret . '&js_code=' . input('post.code') . '&grant_type=authorization_code';

        $userInfo = $this->curl_send($url);
        $userInfo = json_decode($userInfo);
        $this->sessionKey = $userInfo->session_key;

        $this->decryptData(input('post.encryptedData'), input('post.iv'), $data);
        echo json_encode($data);
    }


    /**
     * 检验数据的真实性,并且获取解密后的明文.
     * @param $encryptedData string 加密的用户数据
     * @param $iv string 与用户数据一同返回的初始向量
     * @param $data string 解密后的原文
     *
     * @return int 成功0,失败返回对应的错误码
     */
    public function decryptData( $encryptedData, $iv, &$data )
    {
        if (strlen($this->sessionKey) != 24) {
            return self::$IllegalAesKey;
        }
        $aesKey=base64_decode($this->sessionKey);

        
        if (strlen($iv) != 24) {
            return self::$IllegalIv;
        }
        $aesIV=base64_decode($iv);

        $aesCipher=base64_decode($encryptedData);

        $result=openssl_decrypt( $aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);

        $dataObj=json_decode( $result );
        if( $dataObj  == NULL )
        {
            return self::$IllegalBuffer;
        }
        if( $dataObj->watermark->appid != $this->appid )
        {
            return self::$IllegalBuffer;
        }
        $data = $result;
        return self::$OK;
    }
 
    

    /**
     * curl 请求远程数据
     * @param  [type] $url  需要请求的 url 地址
     * @param  string $data 提交数据
     * @param  string $type 提交方式
     * @return [type]       返回数据
     */
    private function curl_send($url, $data='', $type='GET') {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $type);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
        $tmpInfo = curl_exec($ch);
        curl_close($ch);
        return $tmpInfo;
    }
}

 

    获取手机号信息

 

 参考:

  https://blog.csdn.net/qq_38194393/article/details/81382108

  关于用户微信未绑定手机号的情况:

    来自于 https://me.csdn.net/weixin_41326021 博主的回复

  

 

posted @ 2018-12-25 16:50  梦缘&江南~  阅读(629)  评论(0)    收藏  举报