2020-10-15 微信小程序獲取手機號方法(以PHP為例)

介紹

這里面涉及兩個技術(shù)
1、涉及getPhoneNumber 接口的使用,用以獲取用戶的相應(yīng)信息;
官方文檔:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html

2、涉及開放數(shù)據(jù)的加解密問題
官方文檔:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html
注:要獲取用戶手機號,需要用戶對微信進行手機綁定后才能成功,不然會報獲取失敗

image.png

操作流程:

  • 第一步
    登錄,獲取用戶的 session_key;(這個我就不多說了,不懂的可以去看微信登陸 session_key 的獲取)

  • 第二步
    點擊按鈕調(diào)用 getPhoneNumber事件,得到 encryptedData 和 iv 。把encryptedData 和 iv 傳到后端進行解密。

  • 第三步
    在服務(wù)端通過session_key,encryptedData 和 iv 進行解密,獲得相應(yīng)用戶信息并傳遞給客戶端。

具體示例代碼

前端

wxml

<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">獲取手機號</button>

js

Page({
  getPhoneNumber (e) {
    console.log(e.detail.errMsg)
    console.log(e.detail.iv)
    console.log(e.detail.encryptedData)
  }
})

得到的ivencryptedData 都是一串best64加密后的字符串。大概是這樣子的

iv
iv = 'r7BXXKkLb8qrSNn05n0qiA=='
encryptedData
$encryptedData="CiyLU1Aw2KjvrjMdj8YKliAjtP4gsMZM
                QmRzooG2xrDcvSnxIMXFufNstNGTyaGS
                9uT5geRa0W4oTOb1WT7fJlAC+oNPdbB+
                3hVbJSRgv+4lGOETKUQz6OYStslQ142d
                NCuabNPGBzlooOmB231qMM85d2/fV6Ch
                evvXvQP8Hkue1poOFtnEtpyxVLW1zAo6
                /1Xx1COxFvrc2d7UL/lmHInNlxuacJXw
                u0fjpXfz/YqYzBIBzD6WUfTIF9GRHpOn
                /Hz7saL8xz+W//FRAUid1OksQaQx4CMs
                8LOddcQhULW4ucetDf96JcR3g0gfRK4P
                C7E/r7Z6xNrXd2UIeorGj5Ef7b1pJAYB
                6Y5anaHqZ9J6nKEBvB4DnNLIVWSgARns
                /8wR2SiRS7MNACwTyrGvt9ts8p12PKFd
                lqYTopNHR1Vf7XjfhQlVsAJdNiKdYmYV
                oKlaRv85IfVunYzO0IKXsyl7JCUjCpoG
                20f0a04COwfneQAGGwd5oa+T8yO5hzuy
                Db/XcxxmK01EpqOyuxINew==";

示例圖

image.png

個人代碼示例

  getPhoneNumber:function(e){
    wx.getStorage({
      key: 'cache_key',
      success (cache) {
        // 數(shù)據(jù)請求
        getPhone({cache_key:cache.data,iv:e.detail.iv,encryptedData:e.detail.encryptedData}).then(res=>{
          console.log(res);
        })

      }
    })
  },

注:這個cache_key是我對應(yīng)后端的存儲的 session_key 的key。不懂的可以簡單理解成為這就是我的session_key。直接傳session_key 去請求也是可以的。從安全角度考慮一般session_key 只是放在服務(wù)端的。
getPhone是我封裝的請求函數(shù)

后臺以PHP

后臺官方demo包:點擊下載

示范代碼

wxBizDataCrypt.php(解碼封裝類)

<?php

/**
 * 對微信小程序用戶加密數(shù)據(jù)的解密示例代碼.
 *
 * @copyright Copyright (c) 1998-2014 Tencent Inc.
 */


include_once "errorCode.php";


class WXBizDataCrypt
{
    private $appid;
    private $sessionKey;

    /**
     * 構(gòu)造函數(shù)
     * @param $sessionKey string 用戶在小程序登錄后獲取的會話密鑰
     * @param $appid string 小程序的appid
     */
    public function __construct( $appid, $sessionKey)
    {
        $this->sessionKey = $sessionKey;
        $this->appid = $appid;
    }


    /**
     * 檢驗數(shù)據(jù)的真實性,并且獲取解密后的明文.
     * @param $encryptedData string 加密的用戶數(shù)據(jù)
     * @param $iv string 與用戶數(shù)據(jù)一同返回的初始向量
     * @param $data string 解密后的原文
     *
     * @return int 成功0,失敗返回對應(yīng)的錯誤碼
     */
    public function decryptData( $encryptedData, $iv, &$data )
    {
        if (strlen($this->sessionKey) != 24) {
            return ErrorCode::$IllegalAesKey;
        }
        
        $aesKey=base64_decode($this->sessionKey);

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

        $aesCipher=base64_decode($encryptedData);

        $result=openssl_decrypt( $aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV); // 通過sessionKey iv encryptedData; 解碼。

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

}


errorCode.php(報錯文件)

<?php

/**
 * error code 說明.
 * <ul>

 *    <li>-41001: encodingAesKey 非法</li>
 *    <li>-41003: aes 解密失敗</li>
 *    <li>-41004: 解密后得到的buffer非法</li>
 *    <li>-41005: base64加密失敗</li>
 *    <li>-41016: base64解密失敗</li>
 * </ul>
 */
class ErrorCode
{
    public static $OK = 0;
    public static $IllegalAesKey = -41001;
    public static $IllegalIv = -41002;
    public static $IllegalBuffer = -41003;
    public static $DecodeBase64Error = -41004;
}

?>

demo.php(示范代碼)

<?php

include_once "wxBizDataCrypt.php";


$appid = 'wx4f4bc4dec97d474b';
$sessionKey = 'tiihtNczf5v6AKRyjwEUhQ==';

//請求的時候,三個參數(shù)都是best64 加密后的字符串。如果格式不對,就得檢查一下數(shù)據(jù)格式了

$encryptedData="CiyLU1Aw2KjvrjMdj8YKliAjtP4gsMZM
                QmRzooG2xrDcvSnxIMXFufNstNGTyaGS
                9uT5geRa0W4oTOb1WT7fJlAC+oNPdbB+
                3hVbJSRgv+4lGOETKUQz6OYStslQ142d
                NCuabNPGBzlooOmB231qMM85d2/fV6Ch
                evvXvQP8Hkue1poOFtnEtpyxVLW1zAo6
                /1Xx1COxFvrc2d7UL/lmHInNlxuacJXw
                u0fjpXfz/YqYzBIBzD6WUfTIF9GRHpOn
                /Hz7saL8xz+W//FRAUid1OksQaQx4CMs
                8LOddcQhULW4ucetDf96JcR3g0gfRK4P
                C7E/r7Z6xNrXd2UIeorGj5Ef7b1pJAYB
                6Y5anaHqZ9J6nKEBvB4DnNLIVWSgARns
                /8wR2SiRS7MNACwTyrGvt9ts8p12PKFd
                lqYTopNHR1Vf7XjfhQlVsAJdNiKdYmYV
                oKlaRv85IfVunYzO0IKXsyl7JCUjCpoG
                20f0a04COwfneQAGGwd5oa+T8yO5hzuy
                Db/XcxxmK01EpqOyuxINew==";

$iv = 'r7BXXKkLb8qrSNn05n0qiA==';

$pc = new WXBizDataCrypt($appid, $sessionKey);
$errCode = $pc->decryptData($encryptedData, $iv, $data );

if ($errCode == 0) {
    print($data . "\n");
} else {
    print($errCode . "\n");
}

個人代碼示例(thinkphp6)
/**
     * 解密用戶手機號碼信息
     * @param Request $request
     * @return mixed
     * @throws \Psr\SimpleCache\InvalidArgumentException
     */
    public function getPhone(Request $request){
        $data = UtilService::postMore([
            ['cache_key', ''],
            ['iv', ''],
            ['encryptedData', ''],
        ]);
        $session_key = Cache::get('eb_api_code_' . $data['cache_key']); // 通過cache_key獲取對應(yīng)的session_key
        $phoneData = MiniProgramService::encryptor($session_key, $data['iv'], $data['encryptedData']);
        return app('json')->success($phoneData);
    }
請求結(jié)果
array:4 [
  "phoneNumber" => "18712345678"
  "purePhoneNumber" => "18712345678"
  "countryCode" => "86"
  "watermark" => array:2 [
    "timestamp" => 1658137285
    "appid" => "wxa4582b8c794a603a"
  ]
]

示例圖

image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容