springboot 实现微信小程序授权并解密手机号
生活随笔
收集整理的這篇文章主要介紹了
springboot 实现微信小程序授权并解密手机号
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1.授權
授權是有前端完成的,授權后,前端可以獲取到code,后臺根據code獲取微信小程序用戶對應的openid和session_key,并根據openid判斷是否是新用戶,代碼如下:
| @Value("${app.weixin.mn.appid}") String appidxcx;@Value("${app.weixin.mn.secret}") String secretxcx;@ApiOperation(value = "微信小程序校驗用戶是否存在", httpMethod = "POST", produces = "application/json;charset=UTF-8") @ApiImplicitParam(value = "code", name = "code",defaultValue ="", dataType = "String",paramType="query") @PostMapping("/api/user/checkUserXcx") public Result checkUserXcx(String code){Map<String, Object> data = new HashMap<>();try {String url="https://api.weixin.qq.com/sns/jscode2session?appid="+appidxcx+"&secret="+secretxcx+"&js_code="+ code +"&grant_type=authorization_code";JSONObject jsonObject = AuthUtil.doGetJson(url);if(jsonObject.has("errcode")){Integer errcode = jsonObject.getInt("errcode");if(null!=errcode){String errmsg = jsonObject.getString("errmsg");return Result.fail(errcode,errmsg);}}String openid = jsonObject.getString("openid");String session_key = jsonObject.getString("session_key");User user = userService.getDao().getRepo().findByOpenidxcx(openid);data.put("user",user);data.put("openid",openid);data.put("session_key",session_key);}catch (Exception e){e.printStackTrace();return Result.error(901,"微信小程序校驗用戶失敗!");}return Result.ok(data); } |
2.到此,前端已經獲取到用戶信息了,但是獲取到的用戶手機號是加密的,前端需要傳參數到后臺對手機號進行解密,代碼如下:
| @ApiOperation(value = "解密手機號", httpMethod = "POST", produces = "application/json;charset=UTF-8") @ApiImplicitParams(value = {@ApiImplicitParam(value = "code", name = "sessionKey",defaultValue ="", dataType = "String",paramType="query"),@ApiImplicitParam(value = "encryptedData", name = "encryptedData",defaultValue ="", dataType = "String",paramType="query"),@ApiImplicitParam(value = "iv", name = "iv",defaultValue ="", dataType = "String",paramType="query")}) @PostMapping("/api/user/getUserPhone") public Result getUserPhone(String sessionKey,String encryptedData,String iv){Map<String, Object> data = new HashMap<>();try {String phone = WechatDecryptDataUtil.decryptData(encryptedData, sessionKey, iv);data.put("datas",phone);}catch (Exception e){e.printStackTrace();return Result.error(901,"解密手機號失敗!");}return Result.ok(data); } |
上述代碼中用到的工具類:
WechatDecryptDataUtil.class| import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Base64;import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.Key; import java.security.Security;/*** 微信工具類*/ public class WechatDecryptDataUtil {public static void main(String[] args) {String result = decryptData("CpTbp86N6BtlEDq6r83bGpkGzxvkdaFAWNcKXVQcjY5Ekd+gfAuRC4fwndUEBjbD8WCpuIaR9l6aSUugIJTVdZ6rL8DCZciKS2puvbNYM6zYth2RYEi6YmzRScWINEFIzPBrfP7t/e5ADn7sGMnmGHAZ+6puccgAfjTQnzoS94JqFaF+EHsQCP7IDUpH1zaFiLwdojxDUu3FSfVAV4MYFA==","9y9P6RqKVZiWg==","Yi1SGcsMg==");System.out.println("result = " + result);}public static String decryptData(String encryptDataB64, String sessionKeyB64, String ivB64) {return new String(decryptOfDiyIV(Base64.decode(encryptDataB64),Base64.decode(sessionKeyB64),Base64.decode(ivB64)));}private static final String KEY_ALGORITHM = "AES";private static final String ALGORITHM_STR = "AES/CBC/PKCS7Padding";private static Key key;private static Cipher cipher;private static void init(byte[] keyBytes) {// 如果密鑰不足16位,那么就補足. 這個if 中的內容很重要int base = 16;if (keyBytes.length % base != 0) {int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0);byte[] temp = new byte[groups * base];Arrays.fill(temp, (byte) 0);System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length);keyBytes = temp;}// 初始化Security.addProvider(new BouncyCastleProvider());// 轉化成JAVA的密鑰格式key = new SecretKeySpec(keyBytes, KEY_ALGORITHM);try {// 初始化ciphercipher = Cipher.getInstance(ALGORITHM_STR, "BC");} catch (Exception e) {e.printStackTrace();}}/*** 解密方法** @param encryptedData 要解密的字符串* @param keyBytes 解密密鑰* @param ivs 自定義對稱解密算法初始向量 iv* @return 解密后的字節數組*/private static byte[] decryptOfDiyIV(byte[] encryptedData, byte[] keyBytes, byte[] ivs) {byte[] encryptedText = null;init(keyBytes);try {cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(ivs));encryptedText = cipher.doFinal(encryptedData);} catch (Exception e) {e.printStackTrace();}return encryptedText;}} |
整體思路:
1.前端通過授權獲取到code傳到后臺,后臺根據code獲取openid和session_key返回給前端,此時前端已獲取到用戶所有信息
2.用戶的手機號是加密的,需要解密,前端傳encryptedData、sessionKey和iv到后臺,后臺對手機號進行解密并返回給前端,結束。
總結
以上是生活随笔為你收集整理的springboot 实现微信小程序授权并解密手机号的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: spring boot记录操作日志
- 下一篇: spring boot实现导出数据到ex