微信小程序如何獲取用戶手機號 ?
本篇文章將教會你,使用微信小程序快速、有效獲取用戶手機號的方法。
微信小程序獲取手機號,僅企業小程序支持,個人小程序賬號暫不支持。
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 的綁定事件中獲取所需信息 。
以上就是微信小程序獲取用戶手機號的詳細過程 , 你學會了嗎 ? 如果你有任何疑問 , 歡迎加我個人微信 study2100 , 我會爲你做進一步解答 。