参考文章1:
https://www.jianshu.com/p/c80979950ce6?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation
参考文章2:https://developers.weixin.qq.com/community/develop/doc/0004a8dfe288605a5188675c456000
1、wxml使用getPhoneNumber
2、js向后台发起请求
注意这里要在发起wx.request给后台解密之前使用wx.login接口更新code(用于解密SessionKey),防止code过期,得到的SessionKey也是过期的,再拿去解密手机号会报错pad block corrupted。最好在每次获取手机号前先使用wx.login更新code。
Page({ data: { code: "",//用于解密session_key和openid的code phoneNumber:"" }, onLoad:function(e){ wx.login({ success:res=>{ this.setData({ code:res.code }) } }) }, getPhoneNumber(e){ //如果用户允许获取手机号则返回的数组长度为4 if(Object.getOwnPropertyNames(e.detail).length>1){ //检查code是否过期,如果过期更换新的code wx.checkSession({ success: (res) => { wx.login({ success:res=>{ this.setData({ code:res.code }) } }) }, }) //发起解密手机号请求 wx.request({ url: '后台连接', method: 'POST', data: { code:this.data.code, iv:e.detail.iv, encryptedData:e.detail.encryptedData }, header: { 'content-type': 'application/x-www-form-urlencoded' }, success(res){//控制台打印解密后的手机号 console.log(res.data) } }) } } })
3、SpringBoot获取手机号接口
pom.xml:
commons-httpclient commons-httpclient3.1 org.bouncycastle bcprov-jdk15on1.59 cn.hutool hutool-all4.4.5 org.apache.poi poi-ooxml5.1.0 org.apache.commons commons-lang33.12.0
OpenIdAndSessionKey:
public class OpenIdAndSessionKey { private String openid; private String session_key; public String getOpenid() { return openid; } public void setOpenid(String openid) { this.openid = openid; } public String getSession_key() { return session_key; } public void setSession_key(String session_key) { this.session_key = session_key; } }
UserLoginController:
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.test.utils.AESUtil; import com.test.utils.GetSessionKeyAndOpenId; import org.springframework.web.bind.annotation.*; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.spec.InvalidParameterSpecException; @RestController public class UserLoginController { @PostMapping("/user/login/getOpenId") public String getOpenId(@RequestParam("code")String code) throws IOException { return new GetSessionKeyAndOpenId().getOpenIdAndSessionKey(code).getOpenid(); } @PostMapping("/user/login/getPhoneNumber") public String getPhoneNumber(@RequestParam("code")String code, @RequestParam("iv")String iv, @RequestParam("encryptedData")String encryptedData) throws IOException, InvalidParameterSpecException, NoSuchAlgorithmException, IllegalBlockSizeException, InvalidKeyException, BadPaddingException, InvalidAlgorithmParameterException, NoSuchPaddingException { String sessionKey = new GetSessionKeyAndOpenId().getOpenIdAndSessionKey(code).getSession_key(); JSONObject jsonObject = AESUtil.decrypt(encryptedData,sessionKey,iv); return jsonObject.get("phoneNumber").toString(); } }
AESUtil:
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import org.apache.commons.codec.binary.base64; import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.crypto.*; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.*; import java.security.spec.InvalidParameterSpecException; import static javax.crypto.Cipher.*; public class AESUtil { private static final String KEY_NAME = "AES"; public static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding"; //生成iv public static AlgorithmParameters generateIV(byte[] iv) throws NoSuchAlgorithmException, InvalidParameterSpecException { AlgorithmParameters algorithmParameters = AlgorithmParameters.getInstance(KEY_NAME); algorithmParameters.init(new IvParameterSpec(iv)); return algorithmParameters; } //初始化秘钥 public static void init() throws NoSuchAlgorithmException { Security.addProvider(new BouncyCastleProvider()); KeyGenerator.getInstance(KEY_NAME).init(128); } //生成解密 public static JSONObject decrypt(String encryptedData, String sessionKey, String iv) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, InvalidParameterSpecException { byte[] encrypted64 = base64.decodebase64(encryptedData.getBytes()); byte[] session64 = base64.decodebase64(sessionKey.getBytes()); byte[] iv64 = base64.decodebase64(iv.getBytes()); init(); AlgorithmParameters algorithmParameters = generateIV(iv64); Key key = new SecretKeySpec(session64,KEY_NAME); Cipher cipher = getInstance(CIPHER_ALGORITHM); cipher.init(Cipher.DECRYPT_MODE,key,algorithmParameters); String json = new String(cipher.doFinal(encrypted64)); return JSONUtil.parseObj(json); } }
GetSessionKeyAndOpenId:
import com.fasterxml.jackson.databind.ObjectMapper; import com.test.model.OpenIdAndSessionKey; import java.io.IOException; public class GetSessionKeyAndOpenId { private String appID = "自己的appID"; private String appSecret = "自己的appSecret"; public OpenIdAndSessionKey getOpenIdAndSessionKey(String code) throws IOException { String result = ""; try{ result = HttpUtil.doGet( "https://api.weixin.qq.com/sns/jscode2session?" + "appid=" + this.appID + "&secret=" + this.appSecret + "&js_code=" + code + "&grant_type=authorization_code",null); } catch ( IOException e) { e.printStackTrace(); } ObjectMapper mapper = new ObjectMapper(); OpenIdAndSessionKey openIdJson = mapper.readValue(result, OpenIdAndSessionKey.class); return openIdJson; } }
HttpUtil:
import org.apache.commons.httpclient.HttpState; import org.apache.commons.httpclient.HttpStatus; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLEncoder; import java.util.HashMap; import java.util.Map; import java.util.Set; public class HttpUtil { public static String doGet(String urlPath, HashMapparams) throws IOException { StringBuilder sb = new StringBuilder(urlPath); //在请求的URL后面添加参数,用&分隔 if(params!=null && !params.isEmpty()){ sb.append("?"); Set > set = params.entrySet(); for(Map.Entry entry:set){ String key = entry.getKey(); String value = ""; if(null!=entry.getValue()){ value = entry.getValue().toString(); value = URLEncoder.encode(value,"UTF-8"); } sb.append(key).append("=").append(value).append("&"); } sb.deleteCharAt(sb.length()-1); } URL url = new URL(sb.toString()); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); conn.setConnectTimeout(5000);//超时时间 conn.setRequestMethod("GET"); if(conn.getResponseCode()== HttpStatus.SC_OK){ BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); StringBuilder sbs = new StringBuilder(); String line; while ((line=reader.readLine())!=null){ sbs.append(line); } return sbs.toString(); } return null; } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)