微信小程序获取手机号,后端JAVA解密流程代码
小程序获取手机号,后端JAVA解密流程代码
微信官方文档获取手机号流程地址,先看下最好方便理解下面步骤
实现思路,步骤如下
1.前端需先调用官方wx.login接口获取登录凭证code。
2.后端接收code调用官方接口地址获取用户秘钥sessionKey。
3.前端通过官方getPhoneNumber获取encryptedData,iv
4.前端通过参数**【encryptedData】、【iv】、【sessionKey】**发送请求后端接口,解密用户手机号
小程序获取sessionkey详细接口文档
后端工作如下,
- 1.参数code解密出sessionKey
- {“session_key”:“eF9PAi5P7ZbSaQqkGzEY5g==”,“openid”:“otJ1I4zMSFGDtk7C33O_h6U3IRK8”}
- 2.参数sessionKey,iv,encryptedData解密出手机号
代码如下:
下面工具类很全,放心代码必须全,良心教程。
业务代码Controller
packagecom.df.detection.controller;
importcom.df.detection.base.entity.ResultBean;
importio.swagger.annotations.Api;
importio.swagger.annotations.ApiImplicitParam;
importio.swagger.annotations.ApiImplicitParams;
importorg.apache.commons.codec.binary.Base64;
importorg.json.JSONException;
importorg.springframework.web.bind.annotation.*;
importjava.io.UnsupportedEncodingException;
importjava.security.InvalidAlgorithmParameterException;
importorg.json.JSONObject;
/**
*@AuthorSongzhongjin
*@Date2020/7/1510:09
*@Version1.0
*/
@Api(value="小程序登录授权Controller",tags={"小程序登录授权接口"})
@RestController
@RequestMapping("/app")
publicclassAPPController{
/**
*微信小程序登录获取
*获取session_key
*@param
*@return
*/
@ResponseBody
@PostMapping("/initWxLogin")
@ApiImplicitParams({
@ApiImplicitParam(name="js_code",value="登录时获取的code",paramType="form",dataType="string",required=true)
})
publicResultBeaninitWxLogin(@RequestParam(value="js_code",required=true)Stringjs_code)throwsJSONException{
//测试数据code
//js_code="081ZQ3f91fr9VM1HYdb91y93f91ZQ3fU";
//微信获取session_key接口地址
StringwxLoginUrl="https://api.weixin.qq.com/sns/jscode2session";
//接口参数
Stringparam="appid=小程序id&secret=小程序secret&js_code="+js_code+"&grant_type=authorization_code";
//调用获取session_key接口请求方式get
StringjsonString=GetPostUntil.sendGet(wxLoginUrl,param);
System.out.println(jsonString);
//因为json字符串是大括号包围,所以用JSONObject解析
JSONObjectjson=newJSONObject(jsonString);
//json解析session_key值
Stringsession_key=json.getString("session_key");
System.out.println("session_key:"+session_key);
//返回给前端
returnResultBean.success("session_key",session_key);
}
/**
*解密小程序用户敏感数据
*
*@paramencryptedData明文
*@paramiv加密算法的初始向量
*@paramsessionKey用户秘钥
*@return
*/
@ResponseBody
@PostMapping(value="/decodeUserInfo")
@ApiImplicitParams({
@ApiImplicitParam(name="encryptedData",value="包括敏感数据在内的完整用户信息的加密数据",paramType="form",dataType="string",required=true),
@ApiImplicitParam(name="iv",value="加密算法的初始向量",paramType="form",dataType="string",required=true),
@ApiImplicitParam(name="sessionKey",value="用户秘钥",paramType="form",dataType="string",required=true)
})
publicResultBeandecodeUserInfo(@RequestParam(required=true,value="encryptedData")StringencryptedData,
@RequestParam(required=true,value="iv")Stringiv,
@RequestParam(required=true,value="sessionKey")StringsessionKey
)throwsUnsupportedEncodingException,InvalidAlgorithmParameterException,JSONException{
//AESUtils微信获取手机号解密工具类
AESUtilsaes=newAESUtils();
//调用AESUtils工具类decrypt方法解密获取json串
byte[]resultByte=aes.decrypt(Base64.decodeBase64(encryptedData),Base64.decodeBase64(sessionKey),Base64.decodeBase64(iv));
//判断返回参数是否为空
if(null!=resultByte&&resultByte.length>0){
Stringjsons=newString(resultByte,"UTF-8");
System.out.println(jsons);
JSONObjectjson=newJSONObject(jsons);
//json解析phoneNumber值
StringphoneNumber=json.getString("phoneNumber");
System.out.println("phoneNumber:"+phoneNumber);
returnResultBean.success("手机号",phoneNumber);
}
returnResultBean.error(500,"session_key:失败");
}
}
工具类代码如下
packagecom.df.detection.controller;
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.io.PrintWriter;
importjava.net.URL;
importjava.net.URLConnection;
importjava.util.List;
importjava.util.Map;
/**
*@AuthorSongzhongjin
*@Date2020/7/1510:37
*@Version1.0
*/
publicclassGetPostUntil{
/**
*向指定URL发送GET方法的请求
*
*@paramurl
*发送请求的URL
*@paramparam
*请求参数,请求参数应该是name1=value1&name2=value2的形式。
*@returnURL所代表远程资源的响应结果
*/
publicstaticStringsendGet(Stringurl,Stringparam){
Stringresult="";
BufferedReaderin=null;
try{
StringurlNameString=url+"?"+param;
URLrealUrl=newURL(urlNameString);
//打开和URL之间的连接
URLConnectionconnection=realUrl.openConnection();
//设置通用的请求属性
connection.setRequestProperty("accept","*/*");
connection.setRequestProperty("connection","Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1;SV1)");
//建立实际的连接
connection.connect();
//获取所有响应头字段
Map>map=connection.getHeaderFields();
//遍历所有的响应头字段
for(Stringkey:map.keySet()){
System.out.println(key+"--->"+map.get(key));
}
//定义BufferedReader输入流来读取URL的响应
in=newBufferedReader(newInputStreamReader(
connection.getInputStream()));
Stringline;
while((line=in.readLine())!=null){
result+=line;
}
}catch(Exceptione){
System.out.println("发送GET请求出现异常!"+e);
e.printStackTrace();
}
//使用finally块来关闭输入流
finally{
try{
if(in!=null){
in.close();
}
}catch(Exceptione2){
e2.printStackTrace();
}
}
returnresult;
}
/**
*向指定URL发送POST方法的请求
*
*@paramurl
*发送请求的URL
*@paramparam
*请求参数,请求参数应该是name1=value1&name2=value2的形式。
*@return所代表远程资源的响应结果
*/
publicstaticStringsendPost(Stringurl,Stringparam){
PrintWriterout=null;
BufferedReaderin=null;
Stringresult="";
try{
URLrealUrl=newURL(url);
//打开和URL之间的连接
URLConnectionconn=realUrl.openConnection();
//设置通用的请求属性
conn.setRequestProperty("accept","*/*");
conn.setRequestProperty("connection","Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1;SV1)");
//发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
//获取URLConnection对象对应的输出流
out=newPrintWriter(conn.getOutputStream());
//发送请求参数
out.print(param);
//flush输出流的缓冲
out.flush();
//定义BufferedReader输入流来读取URL的响应
in=newBufferedReader(
newInputStreamReader(conn.getInputStream()));
Stringline;
while((line=in.readLine())!=null){
result+=line;
}
}catch(Exceptione){
System.out.println("发送POST请求出现异常!"+e);
e.printStackTrace();
}
//使用finally块来关闭输出流、输入流
finally{
try{
if(out!=null){
out.close();
}
if(in!=null){
in.close();
}
}
catch(IOExceptionex){
ex.printStackTrace();
}
}
returnresult;
}
}
AESUtils工具类解密手机号
packagecom.df.detection.controller;
importorg.apache.tomcat.util.codec.binary.Base64;
importorg.bouncycastle.jce.provider.BouncyCastleProvider;
importorg.springframework.web.bind.annotation.RequestMapping;
importorg.springframework.web.bind.annotation.RequestParam;
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;
importjavax.xml.transform.Result;
importjava.security.*;
/**
*@AuthorSongzhongjin
*@Date2020/7/1511:46
*@Version1.0
*/
publicclassAESUtils{
publicstaticbooleaninitialized=false;
/**
*AES解密
*@paramcontent密文
*@return
*@throwsInvalidAlgorithmParameterException
*@throwsNoSuchProviderException
*/
publicbyte[]decrypt(byte[]content,byte[]keyByte,byte[]ivByte)throwsInvalidAlgorithmParameterException{
initialize();
try{
Ciphercipher=Cipher.getInstance("AES/CBC/PKCS7Padding");
KeysKeySpec=newSecretKeySpec(keyByte,"AES");
cipher.init(Cipher.DECRYPT_MODE,sKeySpec,generateIV(ivByte));//初始化
byte[]result=cipher.doFinal(content);
returnresult;
}catch(NoSuchAlgorithmExceptione){
e.printStackTrace();
}catch(NoSuchPaddingExceptione){
e.printStackTrace();
}catch(InvalidKeyExceptione){
e.printStackTrace();
}catch(IllegalBlockSizeExceptione){
e.printStackTrace();
}catch(BadPaddingExceptione){
e.printStackTrace();
}catch(NoSuchProviderExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}catch(Exceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
returnnull;
}
publicstaticvoidinitialize(){
if(initialized){
return;
}
Security.addProvider(newBouncyCastleProvider());
initialized=true;
}
//生成iv
publicstaticAlgorithmParametersgenerateIV(byte[]iv)throwsException{
AlgorithmParametersparams=AlgorithmParameters.getInstance("AES");
params.init(newIvParameterSpec(iv));
returnparams;
}
}
接口返回对象ResultBean定义工具类防止有些朋友发现没有这个类
packagecom.df.detection.base.entity; importio.swagger.annotations.ApiModelProperty; /** *@authorLiuYaoguang *@Classnameaaa *@Description *@Date2019/12/0609:22 */ publicclassResultBean{ @ApiModelProperty(value="返回码",dataType="int") privateintcode; @ApiModelProperty(value="返回描述信息",dataType="string") privateStringmessage; @ApiModelProperty(value="返回数据") privateTdata; @ApiModelProperty(value="口令",dataType="string") privateStringtoken; privateResultBean(){ } publicstaticResultBeanerror(intcode,Stringmessage){ ResultBeanresultBean=newResultBean(); resultBean.setCode(code); resultBean.setMessage(message); returnresultBean; } publicstatic ResultBeanerror(intcode,Stringmessage,Tdata){ ResultBeanresultBean=newResultBean(); resultBean.setCode(code); resultBean.setMessage(message); resultBean.setData(data); returnresultBean; } publicstaticResultBeansuccess(Stringmessage){ ResultBeanresultBean=newResultBean(); resultBean.setCode(200); resultBean.setMessage(message); returnresultBean; } publicstatic ResultBeansuccess(Stringmessage,Tdata){ ResultBeanresultBean=newResultBean(); resultBean.setCode(200); resultBean.setMessage(message); resultBean.setData(data); returnresultBean; } publicstaticResultBeansuccess(Stringmessage,Objectdata,Stringtoken){ ResultBeanresultBean=newResultBean(); resultBean.setCode(200); resultBean.setMessage(message); resultBean.setData(data); resultBean.setToken(token); returnresultBean; } publicintgetCode(){ returncode; } publicvoidsetCode(intcode){ this.code=code; } publicStringgetMessage(){ returnmessage; } publicvoidsetMessage(Stringmessage){ this.message=message; } publicTgetData(){ returndata; } publicvoidsetData(Tdata){ this.data=data; } publicStringgetToken(){ returntoken; } publicvoidsetToken(Stringtoken){ this.token=token; } }
以上就是微信小程序获取手机号,后端JAVA解密流程代码的详细内容,更多关于微信小程序获取手机号的资料请关注毛票票其它相关文章!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。