微信小程序登录 后端java
2021/4/30 14:25:31
本文主要是介绍微信小程序登录 后端java,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
微信小程序登录 后端java
- 小程序前端
- java 后端
微信小程序对于2021年4月1日还未发布的小程序,前端根据wx.getUser得到的数据已无法解析到用户信息。更改前端调用接口为wx.getUserProFile,需要用户授权后才可获得用户相关信息。
小程序前端
小程序前端调用wx.login接口可获得code
小程序前端调用wx.getUserProFile 可获得encryptedData 和 iv
java 后端
java后端在获取到对应的数据后访问:https://api.weixin.qq.com/sns/jscode2session换取openid和session_key(用于对数据解码),然后对数据进行解码。
代码如下:
@RequestMapping(value = "login.html") public ResponseVO login(HttpServletRequest request) { String encryptedData = request.getParameter("encryptedData"); String iv = request.getParameter("iv"); String code = request.getParameter("code"); if (StringTool.checkedString(encryptedData, iv, code)) { return ResponseVO.failure("请同意微信读取相关信息!"); } String appid = "小程序appId"; String appSecret = "小程序对应的appSecret"; String apiUrl = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appid + "&secret=" + appSecret + "&js_code=" + code + "&grant_type=authorization_code"; String responseBody = HttpsUtil.doGet(apiUrl); Map<String, String> jsonObject = new Gson().fromJson(responseBody, Map.class); if (!StringTool.checkedString(jsonObject.get("openid")) && !StringTool.checkedString(jsonObject.get("session_key"))) { //查询用户是否存在 PlayerInfo playerInfo = playerInfoService.getMemberByUId(jsonObject.get("openid")); if (playerInfo == null) { //解密获取用户信息 JSONObject userInfoJSON = WechatGetUserInfoUtil.getUserInfo(encryptedData, jsonObject.get("session_key"), iv); if (userInfoJSON != null) { playerInfo = new PlayerInfo(); playerInfo.setUNickName(userInfoJSON.get("nickName").toString());//昵称 playerInfo.setUId(jsonObject.get("openid"));//openId playerInfo.setUCity(userInfoJSON.get("city").toString());//城市 playerInfo.setUSex(Integer.parseInt(userInfoJSON.get("gender").toString()));//性别 playerInfo.setULogo(userInfoJSON.get("avatarUrl").toString());//头像 playerInfoService.addPlayer(playerInfo); } } return ResponseVO.success(playerInfo); } return ResponseVO.failure("登录失败!"); }
HttpsUtil代码如下:
import java.io.IOException; import java.util.Map; import com.google.gson.Gson; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.util.EntityUtils; public class HttpsUtil { public static String doGet(String url) { CloseableHttpClient httpclient = HttpClientBuilder.create().build(); HttpGet httpget = new HttpGet(url); String jsonObj = null; try { HttpResponse response = httpclient.execute(httpget); HttpEntity entity = response.getEntity(); if (entity != null) { String result = EntityUtils.toString(entity, "UTF-8"); jsonObj = result; } } catch (IOException e) { e.printStackTrace(); } return jsonObj; } public static Map<String, Object> doPost(String url, String json) { CloseableHttpClient httpclient = HttpClientBuilder.create().build(); HttpPost httpPost = new HttpPost(url); Map<String, Object> jsonObj = null; try { StringEntity stringEntity = new StringEntity(json, "UTF-8"); httpPost.setEntity(stringEntity); httpPost.addHeader("Accept", "application/json"); httpPost.setHeader("content-type", "application/json"); HttpResponse response = httpclient.execute(httpPost); HttpEntity entity = response.getEntity(); if (entity != null) { String result = EntityUtils.toString(entity, "UTF-8"); jsonObj = new Gson().fromJson(result, Map.class); } } catch (IOException e) { e.printStackTrace(); } return jsonObj; } }
StringTool代码如下:
/** * @version v1.0 * @Description: TODO(字符串检测工具类) * @Author: jyj * @Date: 2020/3/25 0025 11:05 */ public class StringTool { /*** * TODO:检测String是否有为空的情况 * * @param strings * @return */ public static boolean checkedString(String... strings) { for (String str : strings) { if (str == null || str.trim().length() == 0 || str.equals("undefined")) { return true; } } return false; } }
WechatGetUserInfoUtil代码如下:
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.Base64Utils; 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.UnsupportedEncodingException; import java.security.*; import java.security.spec.InvalidParameterSpecException; import java.util.Arrays; import java.util.Base64; /** * @author lqx * @create 2018-08-07 8:30 */ public class WechatGetUserInfoUtil { //日志记录器 private static final Logger log = LoggerFactory.getLogger(WechatGetUserInfoUtil.class); /** * 解密用户敏感数据获取用户信息 * * @param sessionKey 数据进行加密签名的密钥 * @param encryptedData 包括敏感数据在内的完整用户信息的加密数据 * @param iv 加密算法的初始向量 * @return */ public static JSONObject getUserInfo(String encryptedData, String sessionKey, String iv) { // 被加密的数据 byte[] dataByte = Base64Utils.decode(encryptedData.getBytes()); // 加密秘钥 byte[] keyByte = Base64Utils.decode(sessionKey.getBytes()); // 偏移量 byte[] ivByte = Base64Utils.decode(iv.getBytes()); try { // 如果密钥不足16位,那么就补足. 这个if 中的内容很重要 int base = 16; if (keyByte.length % base != 0) { int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0); byte[] temp = new byte[groups * base]; Arrays.fill(temp, (byte) 0); System.arraycopy(keyByte, 0, temp, 0, keyByte.length); keyByte = temp; } // 初始化 Security.addProvider(new BouncyCastleProvider()); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC"); SecretKeySpec spec = new SecretKeySpec(keyByte, "AES"); AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES"); parameters.init(new IvParameterSpec(ivByte)); // 初始化 cipher.init(Cipher.DECRYPT_MODE, spec, parameters); byte[] resultByte = cipher.doFinal(dataByte); if (null != resultByte && resultByte.length > 0) { String result = new String(resultByte, "UTF-8"); return JSON.parseObject(result); } } catch (NoSuchAlgorithmException e) { log.error(e.getMessage(), e); } catch (NoSuchPaddingException e) { log.error(e.getMessage(), e); } catch (InvalidParameterSpecException e) { log.error(e.getMessage(), e); } catch (IllegalBlockSizeException e) { log.error(e.getMessage(), e); } catch (BadPaddingException e) { log.error(e.getMessage(), e); } catch (UnsupportedEncodingException e) { log.error(e.getMessage(), e); } catch (InvalidKeyException e) { log.error(e.getMessage(), e); } catch (InvalidAlgorithmParameterException e) { log.error(e.getMessage(), e); } catch (NoSuchProviderException e) { log.error(e.getMessage(), e); } return null; } }
以上代码居多,不喜原理,能看到这都是遇到问题才来的。其实原理很简单,就是通过前端传入的encryptedData已经包含了对应的用户数据,只是需要重新通过拿到session_key对数据进行解密而已。如有缺少相关类的请留言。
这篇关于微信小程序登录 后端java的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-07-02springboot项目无法注册到nacos-icode9专业技术文章分享
- 2024-06-26结对编程到底难不难?答案在这里
- 2024-06-19《2023版Java工程师》课程升级公告
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt
- 2024-06-05做软件测试需要懂代码吗?
- 2024-06-0514-ShardingSphere的分布式主键实现
- 2024-06-03为什么以及如何要进行架构设计权衡?
- 2024-05-31全网首发第二弹!软考2024年5月《软件设计师》真题+解析+答案!(11-20题)