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


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

    小程序获取code。
    后台得到session_key,openid。

    组件触发getPhoneNumber

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

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

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

    <button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber"></button>
    Page({
      getPhoneNumber(e) {
        console.log(e.detail.errMsg)
        console.log(e.detail.iv)
        console.log(e.detail.encryptedData)
      }
    })
    

    encryptedData 解密

    encryptedData 解密后为以下 JSON 结构

    {
      "phoneNumber": "13580006666",
      "purePhoneNumber": "13580006666",
      "countryCode": "86",
      "watermark": {
        "appid": "APPID",
        "timestamp": TIMESTAMP
      }
    }
    

    小程序可以通过各种前端接口获取微信提供的开放数据。考虑到开发者服务器也需要获取这些开放数据,微信会对这些数据做签名和加密处理。开发者后台拿到开放数据后可以对数据进行校验签名和解密,来保证数据不被篡改。

    签名校验以及数据加解密涉及用户的会话密钥 session_key。 开发者应该事先通过 wx.login 登录流程获取会话密钥 session_key 并保存在服务器。为了数据不被篡改,开发者不应该把 session_key 传到小程序客户端等服务器外的环境。

    接口返回的加密数据(encryptedData) 进行对称解密。 解密算法如下:

    对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充。
    对称解密的目标密文为 Base64_Decode(encryptedData)。
    对称解密秘钥 aeskey = Base64_Decode(session_key), aeskey 是16字节。
    对称解密算法初始向量 为Base64_Decode(iv),其中iv由数据接口返回。

    会话密钥 session_key 有效性

    开发者如果遇到因为 session_key 不正确而校验签名失败或解密失败,请关注下面几个与 session_key 有关的注意事项。

    wx.login 调用时,用户的 session_key 可能会被更新而致使旧 session_key 失效(刷新机制存在最短周期,如果同一个用户短时间内多次调用 wx.login,并非每次调用都导致 session_key 刷新)。开发者应该在明确需要重新登录时才调用 wx.login,及时通过 code2Session 接口更新服务器存储的 session_key。
    微信不会把 session_key 的有效期告知开发者。我们会根据用户使用小程序的行为对 session_key 进行续期。用户越频繁使用小程序,session_key 有效期越长。
    开发者在 session_key 失效时,可以通过重新执行登录流程获取有效的 session_key。使用接口 wx.checkSession可以校验 session_key 是否有效,从而避免小程序反复执行登录流程。
    当开发者在实现自定义登录态时,可以考虑以 session_key 有效期作为自身登录态有效期,也可以实现自定义的时效性策略。

    <?php
    
    /**
     * 对微信小程序用户加密数据的解密示例代码.
     *
     * @copyright Copyright (c) 1998-2014 Tencent Inc.
     */
    namespace wechat;
    
    class wxBizDataCrypt
    {
        private $appid;
    	private $sessionKey;
    
    	/**
    	 * 构造函数
    	 * @param $sessionKey string 用户在小程序登录后获取的会话密钥
    	 * @param $appid string 小程序的appid
    	 */
    	public function __construct( $appid, $sessionKey)
    	{
    		$this->sessionKey = $sessionKey;
    		$this->appid = $appid;
    	}
    
    
    	/**
    	 * 检验数据的真实性,并且获取解密后的明文.
    	 * @param $encryptedData string 加密的用户数据
    	 * @param $iv string 与用户数据一同返回的初始向量
    	 * @param $data string 解密后的原文
         *
    	 * @return int 成功0,失败返回对应的错误码
    	 */
    	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);
    
    		$dataObj=json_decode( $result );
    		if( $dataObj  == NULL )
    		{
    			return errorCode::$IllegalBuffer;
    		}
    		if( $dataObj->watermark->appid != $this->appid )
    		{
    			return errorCode::$IllegalBuffer;
    		}
    		$data = $result;
    		return errorCode::$OK;
    	}
    
    }
    
    /**
     * 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;
    }
    
    

    改造

    <?php
    
    /**
     * 对微信小程序用户加密数据的解密示例代码.
     *
     * @copyright Copyright (c) 1998-2014 Tencent Inc.
     */
    namespace wechat;
    
    
    class wxBizDataCrypt
    {
        private $appid;
    	private $sessionKey;
    
        /**
         * error code 说明.
         * <ul>
    
         *    <li>-41001: encodingAesKey 非法</li>
         *    <li>-41003: aes 解密失败</li>
         *    <li>-41004: 解密后得到的buffer非法</li>
         *    <li>-41005: base64加密失败</li>
         *    <li>-41016: base64解密失败</li>
         * </ul>
         */
        public static $OK = 0;
        public static $IllegalAesKey = -41001;
        public static $IllegalIv = -41002;
        public static $IllegalBuffer = -41003;
        public static $DecodeBase64Error = -41004;
    
    	/**
    	 * 构造函数
    	 * @param $sessionKey string 用户在小程序登录后获取的会话密钥
    	 * @param $appid string 小程序的appid
    	 */
    	public function __construct( $appid, $sessionKey)
    	{
    		$this->sessionKey = $sessionKey;
    		$this->appid = $appid;
    	}
    
    
    	/**
    	 * 检验数据的真实性,并且获取解密后的明文.
    	 * @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;
    	}
    
    }
    
    
    
    
    /*$appid = 'wx4f4bc4dec97d474b';
    $sessionKey = 'tiihtNczf5v6AKRyjwEUhQ==';
    
    $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 . "
    ");
    } else {
        print($errCode . "
    ");
    }*/
    
    
    
    
    
    
  • 相关阅读:
    年年岁岁花相似,岁岁年年竟相同
    两情相悦,亦或情投意合
    FreeBSD学习笔记1
    MySQL学习笔记2
    门户网站镜像站以及CDN技术
    候车
    MySQL学习笔记1
    JDBC | 第一章: 快速开始使用JDBC连接Mysql数据库之简单CRUD
    JDBC | 第零章: 什么是JDBC?
    JDBC | 第二章: JDBC之批量更新,添加,和删除操作
  • 原文地址:https://www.cnblogs.com/jiqing9006/p/10288305.html
Copyright © 2020-2023  润新知