小程序官方文档中介绍:
获取微信用户绑定的手机号,需先调用wx.login接口。
因为需要用户主动触发才能发起获取手机号接口,所以该功能不由 API 来调用,需用 button 组件的点击来触发。
注意:目前该接口针对非个人开发者,且完成了认证的小程序开放(不包含海外主体)。需谨慎使用,若用户举报较多或被发现在不必要场景下使用,微信有权永久回收该小程序的该接口权限。具体可参考小程序官方文档
使用方法
需要将 button 组件 open-type 的值设置为 getPhoneNumber,当用户点击并同意之后,可以通过 bindgetphonenumber 事件回调获取到微信服务器返回的加密数据, 然后在第三方服务端结合 session_key 以及 app_id 进行解密获取手机号。
<buttonopen-type="getPhoneNumber"bindgetphonenumber="getPhoneNumber">获取手机号button>
在使用组件之前先调用login
onLaunch:function(){ wx.login({ success:function(res){ if(res.code){ this.globalData.code=res.code; }else{ console.log('获取用户登录态失败!'+res.errMsg) } } }); }, globalData:{} })App({
getPhoneNumber中将返回用户是否同意授权的数据,
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); } }) } } })constApp=getApp();
后端需要根据前端传递的code,iv, encryptedData,结合小程序的appID,secret,先获取session_key,然后在进行电话号码解析。为了安全考虑,我们的appID和secret都是存放在后端的,所以获取session_key和电话解析都放后端进行了,前端只需调用接口即可。
获取session_key的地址
constSECRET=''; constBASE_URL='https://api.'; consturl=`${BASE_URL}/sns/jscode2session?appid=${APP_ID}&secret=${SECRET}&js_code=${res.code}&grant_type=authorization_code`;constAPP_ID='';
电话号码解析实例(java版)
importorg.springframework.stereotype.Controller; importorg.springframework.web.bind.annotation.RequestMapping; importorg.springframework.web.bind.annotation.ResponseBody; importjavax.crypto.BadPaddingException; importjavax.crypto.Cipher; importjavax.crypto.IllegalBlockSizeException; importjavax.crypto.NoSuchPaddingException; importjavax.crypto.spec.IvParameterSpec; importjavax.crypto.spec.SecretKeySpec; importjava.io.IOException; importjava.io.UnsupportedEncodingException; importjava.security.InvalidAlgorithmParameterException; importjava.security.InvalidKeyException; importjava.security.NoSuchAlgorithmException; importjava.security.spec.AlgorithmParameterSpec; @Controller publicclassGetPhone{ /*用户手机号解析*/ @RequestMapping("/getPhoneNumber") @ResponseBody publicStringgetPhoneNumber(StringencryptedData,Stringiv,StringsessionKey)throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidAlgorithmParameterException,InvalidKeyException,BadPaddingException,IllegalBlockSizeException,UnsupportedEncodingException{ byte[]encData=Base64.decode(encryptedData); byte[]keyByte=Base64.decode(iv); byte[]key=Base64.decode(sessionKey); AlgorithmParameterSpecivSpec=newIvParameterSpec(keyByte); Ciphercipher=Cipher.getInstance("AES/CBC/PKCS5Padding"); SecretKeySpeckeySpec=newSecretKeySpec(key,"AES"); cipher.init(Cipher.DECRYPT_MODE,keySpec,ivSpec);//初始化 byte[]resultByte=cipher.doFinal(encData); if(null!=resultByte&&resultByte.length>0){ Stringresult=newString(resultByte,"UTF-8"); System.out.println(result); returnresult; } returnnull; }importorg.apache.shiro.codec.Base64;
注意:在回调中调用 wx.login 登录,可能会刷新登录态。此时服务器使用 code 换取的 sessionKey 不是加密时使用的 sessionKey,导致解密失败。建议开发者提前进行 login;或者在回调中先使用 checkSession 进行登录态检查,避免 login 刷新登录态。
最后提醒大家,进入一个未知的小程序时,弹出用户授权询问框时,谨慎授权。
如下图所示。