前言:
最近公司做一个支付宝小程序项目,用支付宝userId做唯一用户id,后台encryptedData解密出用户支付宝绑定的手机号信息,其中
参数:authToken和encryptedData均为前端传入,需要和前端协调开发。
正文开始:
贴代码:
public String findUserId(String authCode) throws AdminException, AlipayApiException { AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.url, AlipayConfig.app_id, AlipayConfig.private_key, AlipayConfig.format, AlipayConfig.charset, AlipayConfig.public_key, AlipayConfig.signtype); AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest(); request.setGrantType("authorization_code"); request.setCode(authCode); // request.setRefreshToken("201208134b203fe6c11548bcabd8da5bb087a83b"); AlipaySystemOauthTokenResponse response = alipayClient.execute(request); //String accessToken = response.getAccessToken(); if (response.isSuccess()) { //log.info("调用成功"); //log.info("支付宝用户唯一id:" + response.getUserId()); // log.info("token令牌:" + response.getAccessToken()); //访问令牌。通过该令牌调用需要授权类接口 return response.getUserId(); } return null; }
其中的accessToken我没有用到,你们用到了解除注释就可以,亲测可以获取到。
2.encryptedData解密手机号:
//解密手机号 JSONObject jsonObject =JSONObject.parseObject(userSmallLoginRequest.getEncryptedData()); String phoneResult = AESCBCUtil.RealDecrypt(jsonObject.getString("response"), AlipayConfig.aesSecretKey); JSONObject jsonObject1 = JSONObject.parseObject(phoneResult); if(!"10000".equals(jsonObject1.getString("code"))){ throw new AdminException("用户手机号解密失败"); } String phone = jsonObject1.getString("mobile");
其中的AlipayConfig.aesSecretKey是支付宝小程序设置的密钥
贴工具类:
package com.dq.utils; import com.alipay.api.internal.util.codec.Base64; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; /** * @author: martin * @date: 2018/8/21 20:11 * @description: */ public class AESCBCUtil { /** * * @param content 密文 * @param key aes密钥 * @return 原文 */ public static String RealDecrypt(String content, String key) throws Exception { //反序列化AES密钥 SecretKeySpec keySpec = new SecretKeySpec(Base64.decodeBase64(key.getBytes()), "AES"); //128bit全零的IV向量 byte[] iv = new byte[16]; for (int i = 0; i < iv.length; i++) { iv[i] = 0; } IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); //初始化加密器并加密 Cipher deCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); deCipher.init(Cipher.DECRYPT_MODE, keySpec, ivParameterSpec); byte[] encryptedBytes = Base64.decodeBase64(content.getBytes()); byte[] bytes = deCipher.doFinal(encryptedBytes); return new String(bytes); } }
其中userSmallLoginRequest.getEncryptedData()为传入的加密串,phone就是拿到的手机号,JSONObject为阿里巴巴的fastjson,前端获取代码是 官方链接:
my.getPhoneNumber({ success: (res) => { let encryptedData = res.response; my.request({ url: '你的后端服务端', data: encryptedData, }); }, fail: (res) => { console.log(res); console.log('getPhoneNumber_fail'); }, });
其中传入后端的data格式应该是:
{"response": "","xx":"xxx"}
经过我们业务逻辑解析出来的格式应该是:
{ "code": "10000", "msg": "Success", "mobile": "1597671905" }
mobile就是手机号,没了。