​微信小程式如何獲取用戶手機號 ?

微信小程式如何獲取用戶手機號 ?

本篇文章將教會你,使用微信小程式快速、有效獲取用戶手機號的方法。 微信小程式獲取手機號,僅企業小程式支援,個人小程式帳號暫不支援。

1、小程式端調用 wx.login() 方法,獲取 code 後,將 code 通過後台 api 介面傳遞到後台。

  /**     * 獲取openid、userToken     */    getServerUserInfo: function (e) {      let that = this      wx.login({        success: function (res) {          if (res.code) {            wx.request({              url: app.serverUrl + 'api/login/getUserInfo',              data: {                code: res.code              },              header: {                'content-type': 'application/json'              },              success: function (e) {                that.setData({                  userToken: e.data.userToken,                })              }            })          }        }      })    },

2、後台 api 介面收到 code 後,調用微信介面 jscode2session , 換取 openid 、 session_key 、 unionid

這裡有三個知識點必須十分清楚:

1)unionid : 同一用戶 ,在同一開發平台下,多個應用 unionid 相同 。 不同應用下 openid 是不同的 , 若需要打通多個應用的用戶體系 , unionid 是唯一的做法。

2) session_key : 為應用安全,session_key 不應該直接傳遞到小程式端 , 正確的做法是將 session_key 存儲在伺服器端 。

session_key 存儲方式這裡以 redis 為例進行講解,調用 jscode2session 介面返回的數據有 openid 和 session_key , openid 是唯一的 , 因此 redis 存儲的 key 可以為 openid 的 MD5 加密字元串 , value 為 session_key , 有效期可設置為 10 min(你認為的合適的有效期) , openid 的加密字元串作為 userToken 返回給小程式 , 這樣我們在使用的時候 , 就可以通過 userToken 來換取 session_key 。

3)session_key 有效期:微信平台不會告訴我們 session_key 準確的有效期 , 會有過期的情況出現 , 如何驗證 session_key 的有效性呢 ? 在小程式端可以使用 wx.checkSession() 方法來驗證 session_key 有效性 ,若 session_key 失效 ,則需要重新執行 wx.login() 方法 , 也就是從第一步開始重新執行 。

這裡使用 Java 語言編寫 , 程式碼如下 :

    /**       * 獲取用戶資訊       * @param request       * @return       */      @RequestMapping("/getUserInfo")      @ResponseBody      private WxLoginResult getUserInfo(HttpServletRequest request) {          String code = request.getParameter("code");          WxLoginResult wxLoginResult = null;          String urlStr = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appId + "&secret=" + appSecret + "&js_code=" + code + "&grant_type=authorization_code";          try {              URL url = new URL(urlStr);              HttpURLConnection connection = (HttpURLConnection) url.openConnection();              connection.connect();              BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));              String line;              StringBuilder sb = new StringBuilder();              while ((line = br.readLine()) != null) {                  sb.append(line);              }              br.close();              connection.disconnect();              System.out.println(sb.toString());              String result = sb.toString();              wxLoginResult = new Gson().fromJson(result, WxLoginResult.class);              String userToken = Md5Util.encode(wxLoginResult.getOpenid());              wxLoginResult.setUserToken(userToken);              redisCacheUtil.setCacheObject(userToken, wxLoginResult.getSession_key());          } catch (Exception e) {              e.printStackTrace();          }          wxLoginResult.setSession_key("");          return wxLoginResult;      }

3、小程式端提交 code 調用後台 api 介面後 , 獲取 api 介面返回的 userToken ,通過頁面 button 點擊調用後台介面 , 傳遞參數 userToken 、 iv 、 encryptedData 到後台進行數據解密,得到 phoneNumber

1)頁面設置

<button class="btn"  open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">{{phoneNumber==null?'獲取手機號':phoneNumber}}</button>

2) 獲取手機號 button 點擊後將獲取到 encryptedData 和 iv ,即可調用後台 api 介面獲取手機號

getPhoneNumber: function (e) {      var that = this;      if (e.detail.errMsg == "getPhoneNumber:ok") {        wx.request({          url: app.serverUrl+'/api/login/decodePhone',          data: {            encryptedData: e.detail.encryptedData,            iv: e.detail.iv,            userToken: that.data.userToken,          },          header: {            'content-type': 'application/json'          },          success: function (res) {            that.setData({              phoneNumber:res.data.phoneNumber            })          }        })      }    },

3) 後台 api 介面接收參數 : encryptedData 、 iv 、 userToken 解密出手機號 phoneNumber ,這裡解密演算法為 Java 語言編寫 , 程式碼如下 :

    /**       * 解密用戶資訊       */      public static String getUserInfo(String encryptedData, String sessionKey, String iv) {          byte[] dataByte = Base64.decode(encryptedData);          byte[] keyByte = Base64.decode(sessionKey);          byte[] ivByte = Base64.decode(iv);          try {              int base = 16;              if (keyByte.length % base != 0) {                  int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);                  byte[] temp = new byte[groups * base];                  Arrays.fill(temp, (byte) 0);                  System.arraycopy(keyByte, 0, temp, 0, keyByte.length);                  keyByte = temp;              }              Security.addProvider(new BouncyCastleProvider());              Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");              SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");              AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");              parameters.init(new IvParameterSpec(ivByte));              cipher.init(Cipher.DECRYPT_MODE, spec, parameters);              byte[] resultByte = cipher.doFinal(dataByte);              if (null != resultByte && resultByte.length > 0) {                  String result = new String(resultByte, "UTF-8");                  return result;              }          } catch (NoSuchAlgorithmException e) {              e.printStackTrace();          } catch (NoSuchPaddingException e) {              e.printStackTrace();          } catch (InvalidParameterSpecException e) {              e.printStackTrace();          } catch (IllegalBlockSizeException e) {              e.printStackTrace();          } catch (BadPaddingException e) {              e.printStackTrace();          } catch (UnsupportedEncodingException e) {              e.printStackTrace();          } catch (InvalidKeyException e) {              e.printStackTrace();          } catch (InvalidAlgorithmParameterException e) {              e.printStackTrace();          } catch (NoSuchProviderException e) {              e.printStackTrace();          }          return null;      }

總結:

1) 解密 encryptedData 數據十分重要 , 我第一次做 encryptedData 解密的時候花了不少時間。

2) session_key 的正確處理方式是伺服器保存 , 將可以獲取 session_key 的鑰匙傳遞給小程式端 , 防止出現安全問題 。

3) 小程式端發起獲取用戶手機號操作,必須使用 button 並設置 open-type="getPhoneNumber" ,並從 button 的綁定事件中獲取所需資訊 。

以上就是微信小程式獲取用戶手機號的詳細過程 , 你學會了嗎 ?