网页手机号抓取程序(小程序开发如何获取用户授权参数第三?算法解密 )
优采云 发布时间: 2022-04-14 10:34网页手机号抓取程序(小程序开发如何获取用户授权参数第三?算法解密
)
在开发小程序的过程中,我们经常会涉及到用户身份的问题。最常见的一种是我们需要获取用户的手机号。通过微信获取手机号后,可以减少很多操作,比如用户手机号验证等,我们也可以给用户发送提醒短信,所以本文主要讲解如何获取用户手机号电话号码。
获取用户手机号分为以下几个步骤:
首先点击页面获取授权按钮
第二个获取用户授权参数
三、根据加解密算法解密手机号
接下来,我们将实现以上三个步骤
先看首页
获取用户信息
获取手机号码
{{userInfo.nickName}}
{{userInfo.phone}}
男
女
选择职业
{{array[index]}}
选择地区
{{items[i].name}}
注册
大约只要
我只是跳过了获取用户的头像,还有更多在线信息
接下来我们看关键代码
在这里定义
getPhoneNumber 是微信官方要求获取用户手机号授权
onGetPhoneNumber是一个回调函数,获取授权后会回调到该方法,即获取到的电话号码在该函数的返回值中。当然这个函数是自定义的,可以随意命名,但是上面的getPhoneNumber不能随便修改。
接下来,我们通过服务器获取授权
上面的代码:这里是js调用我们自己的后端,我们的后端调用微信服务器
onGetPhoneNumber(e) {
var that = this;
wx.login({
success (res) {
if (res.code) {
console.log('步骤2获检查用户登录状态,获取用户电话号码!', res)
wx.request({
url: '这里写自己的获取授权的服务器地址',
data: {code: res.code},
header: {'content-type': 'application/json'},
success: function(res) {
console.log("步骤三获取授权码,获取授权openid,session_key",res);
var userphone=res.data.data;
wx.setStorageSync('userphoneKey',userphone);
//解密手机号
var msg = e.detail.errMsg;
var sessionID=wx.getStorageSync("userphoneKey").session_key;
var encryptedData=e.detail.encryptedData;
var iv=e.detail.iv;
if (msg == 'getPhoneNumber:ok') {//这里表示获取授权成功
wx.checkSession({
success:function(){
//这里进行请求服务端解密手机号
that.deciyption(sessionID,encryptedData,iv);
},
fail:function(){
// that.userlogin()
}
})
}
},fail:function(res){
console.log("fail",res);
}
})
} else {
console.log('登录失败!' + res.errMsg)
}
}
})
后台调用微信获取授权码
下面是通过我写的框架调用的。您无需关心注释内容。只需要关注自己的框架注解即可。不管是spring还是servlet,只要请求可以进入方法,所以重点放在中间部分,把参数值正确传进去
/**
* 回调微信登录信息
* @param request
* @param response
*/
@MethodAnnotation(method="miniGetAuth",methoddes="小程序授权",methodWay="ALL")
public void miniGetAuth(HttpServletRequest request, HttpServletResponse response) throws Exception{
String url="https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code";
String code= request.getParameter("code");
if(empty(code))return;
url=url.replaceAll("APPID", PropertiesUtil.wx_appid)
.replaceAll("SECRET", PropertiesUtil.wx_appsecret)
.replaceAll("JSCODE", code);
qury(request, response, WeixinUtil.doGetStr(url), false, 0);
}
下面是工具类方法 WeixinUtil.doGetStr(url)
/**
* get请求
* @param url
* @return
* @throws ParseException
* @throws IOException
*/
public static JSONObject doGetStr(String url) throws ParseException, IOException{
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
JSONObject jsonObject = null;
HttpResponse httpResponse = client.execute(httpGet);
HttpEntity entity = httpResponse.getEntity();
if(entity != null){
String result = EntityUtils.toString(entity,"UTF-8");
jsonObject = JSONObject.fromObject(result);
}
return jsonObject;
}
这个值可以返回给前端,前端可以接收以下参数
然后我们获取授权后的第三个参数iv,调用如下方法解密服务端
that.deciyption(sessionID,encryptedData,iv);
deciyption(sessionID,encryptedData,iv){
var that = this;
console.log("步骤4根据秘钥解密手机号码sessionID:",sessionID);
wx.request({
url: '解密地址',
data: {
sessionID: sessionID,
encryptedData:encryptedData,
iv: iv
},
header: {'content-type': 'application/json'},
success: function(res) {
console.log("79",(res.data.code==20001));
if(res.data.code==20001){//这里不用管,可以删掉,我的框架里返回值20001是授权失败,可按照自己逻辑处理
console.log("获取失败,重新获取",res);
that.setData({
showPhone:true,
})
}else{
console.log("line 79", JSON.parse(res.data.data));
var json= JSON.parse(res.data.data);
wx.setStorageSync('userphone', JSON.parse(res.data.data).phoneNumber);
console.log("步骤5解密成功",res.data.data);
that.setData({
showPhone:false,
"userInfo.phone":wx.getStorageSync('userphone')
})
}
},fail:function(res){
console.log("fail",res);
}
})
}
服务器解密代码
/**
*
* @param request
* @param response
* @throws Exception
*/
@MethodAnnotation(method="miniGetPhone",methoddes="小程序解密手机号",methodWay="ALL")
public void miniGetPhone(HttpServletRequest request, HttpServletResponse response) throws Exception{
String encrypdata= request.getParameter("encryptedData");
String ivdata= request.getParameter("iv");
String sessionkey= request.getParameter("sessionID");
if(empty(encrypdata,ivdata,sessionkey))return;
qury(request, response, deciphering(encrypdata, ivdata, sessionkey), false, 0);
}
解密解密方法
public static String deciphering(String encrypdata,String ivdata, String sessionkey) {
byte[] encrypData = Base64.decode(encrypdata);
byte[] ivData = Base64.decode(ivdata);
byte[] sessionKey = Base64.decode(sessionkey);
String str="";
try {
str = decrypt(sessionKey,ivData,encrypData);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return str;
}
public static String decrypt(byte[] key, byte[] iv, byte[] encData) throws Exception {
AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
return new String(cipher.doFinal(encData),"UTF-8");
}
最终效果