小程序官方文檔中介紹:
獲取微信用戶綁定的手機號,需先調(diào)用wx.login接口。 因為需要用戶主動觸發(fā)才能發(fā)起獲取手機號接口,所以該功能不由 API 來調(diào)用,需用 button 組件的點擊來觸發(fā)。
注意:目前該接口針對非個人開發(fā)者,且完成了認證的小程序開放(不包含海外主體)。需謹慎使用,若用戶舉報較多或被發(fā)現(xiàn)在不必要場景下使用,微信有權永久回收該小程序的該接口權限。具體可參考小程序API
使用方法 需要將 button 組件 open-type 的值設置為 getPhoneNumber,當用戶點擊并同意之后,可以通過 bindgetphonenumber 事件回調(diào)獲取到微信服務器返回的加密數(shù)據(jù), 然后在第三方服務端結合 session_key 以及 app_id 進行解密獲取手機號。
復制代碼
在使用組件之前先調(diào)用login
App({
onLaunch: function () {
wx.login({
success: function (res) {
if (res.code) {
//發(fā)起網(wǎng)絡請求
this.globalData.code = res.code;
console.log(res.code)
} else {
console.log('獲取用戶登錄態(tài)失??!' + res.errMsg)
}
}
});
},
globalData: {}
})
復制代碼
getPhoneNumber中將返回用戶是否同意授權的數(shù)據(jù),
const App = getApp();
Page({
getPhoneNumber(e) {
const { iv, encryptedData, errMsg } = e.detail;
if (errMsg === 'getPhoneNumber:ok') {
// 同意授權
wx.request({
url: '/GetPhone',
data: {
code: App.globalData.code,
iv,
encryptedData
},
success: (res) => {
console.log(res);
}
})
}
}
})
復制代碼
后端需要根據(jù)前端傳遞的code,iv, encryptedData,結合小程序的appID,secret,先獲取session_key,然后在進行電話號碼解析。為了安全考慮,我們的appID和secret都是存放在后端的,所以獲取session_key和電話解析都放后端進行了,前端只需調(diào)用接口即可。
獲取session_key的地址
const APP_ID = '';
const SECRET = '';
const BASE_URL = 'https://api.weixin.qq.com';
const url = `${BASE_URL}/sns/jscode2session?appid=${APP_ID}&secret=${SECRET}&js_code=${res.code}&grant_type=authorization_code`;
復制代碼
電話號碼解析實例(java版)
import org.apache.shiro.codec.Base64;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.AlgorithmParameterSpec;
@Controller
public class GetPhone {
/*用戶手機號解析*/
@RequestMapping("/getPhoneNumber")
@ResponseBody
public String getPhoneNumber(String encryptedData, String iv, String sessionKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {
System.out.println(encryptedData + "-------" + iv + "-------" + sessionKey);
byte[] encData = http://www.wxapp-union.com/Base64.decode(encryptedData);
byte[] keyByte = Base64.decode(iv);
byte[] key = Base64.decode(sessionKey);
AlgorithmParameterSpec ivSpec = new IvParameterSpec(keyByte);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);// 初始化
byte[] resultByte = cipher.doFinal(encData);
if (null != resultByte && resultByte.length > 0) {
String result = new String(resultByte, "UTF-8");
System.out.println(result);
return result;
}
return null;
}
復制代碼
注意:在回調(diào)中調(diào)用 wx.login 登錄,可能會刷新登錄態(tài)。此時服務器使用 code 換取的 sessionKey 不是加密時使用的 sessionKey,導致解密失敗。建議開發(fā)者提前進行 login;或者在回調(diào)中先使用 checkSession 進行登錄態(tài)檢查,避免 login 刷新登錄態(tài)。
最后提醒大家,進入一個未知的小程序時,彈出用戶授權詢問框時,謹慎授權。如下圖