mirror of
				https://gitee.com/binary/weixin-java-tools.git
				synced 2025-10-31 02:28:25 +08:00 
			
		
		
		
	#659 小程序增加上报用户数据后台接口
This commit is contained in:
		| @ -0,0 +1,40 @@ | ||||
| package me.chanjar.weixin.common.util; | ||||
|  | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.apache.commons.codec.binary.Hex; | ||||
|  | ||||
| import javax.crypto.Mac; | ||||
| import javax.crypto.spec.SecretKeySpec; | ||||
| import java.security.InvalidKeyException; | ||||
| import java.security.NoSuchAlgorithmException; | ||||
|  | ||||
| /** | ||||
|  * <pre> | ||||
|  *  签名工具类 | ||||
|  *  Created by BinaryWang on 2018/7/11. | ||||
|  * </pre> | ||||
|  * | ||||
|  * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||
|  */ | ||||
| @Slf4j | ||||
| public class SignUtils { | ||||
|   /** | ||||
|    * HmacSHA256 签名算法 | ||||
|    * | ||||
|    * @param message 签名数据 | ||||
|    * @param key     签名密钥 | ||||
|    */ | ||||
|   public static String createHmacSha256Sign(String message, String key) { | ||||
|     try { | ||||
|       Mac sha256 = Mac.getInstance("HmacSHA256"); | ||||
|       SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "HmacSHA256"); | ||||
|       sha256.init(secretKeySpec); | ||||
|       byte[] bytes = sha256.doFinal(message.getBytes()); | ||||
|       return Hex.encodeHexString(bytes).toUpperCase(); | ||||
|     } catch (NoSuchAlgorithmException | InvalidKeyException e) { | ||||
|       SignUtils.log.error(e.getMessage(), e); | ||||
|     } | ||||
|  | ||||
|     return null; | ||||
|   } | ||||
| } | ||||
| @ -5,6 +5,8 @@ import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; | ||||
| import cn.binarywang.wx.miniapp.bean.WxMaUserInfo; | ||||
| import me.chanjar.weixin.common.error.WxErrorException; | ||||
|  | ||||
| import java.util.Map; | ||||
|  | ||||
| /** | ||||
|  * 用户信息相关操作接口. | ||||
|  * | ||||
| @ -28,6 +30,16 @@ public interface WxMaUserService { | ||||
|    */ | ||||
|   WxMaUserInfo getUserInfo(String sessionKey, String encryptedData, String ivStr); | ||||
|  | ||||
|   /** | ||||
|    * 上报用户数据后台接口. | ||||
|    * <p>小游戏可以通过本接口上报key-value数据到用户的CloudStorage。</p> | ||||
|    * 文档参考https://developers.weixin.qq.com/minigame/dev/document/open-api/data/setUserStorage.html | ||||
|    *  @param kvMap      要上报的数据 | ||||
|    * @param sessionKey 通过wx.login 获得的登录态 | ||||
|    * @param openid | ||||
|    */ | ||||
|   void setUserStorage(Map<String, String> kvMap, String sessionKey, String openid) throws WxErrorException; | ||||
|  | ||||
|   /** | ||||
|    * 解密用户手机号信息. | ||||
|    * | ||||
|  | ||||
| @ -1,14 +1,25 @@ | ||||
| package cn.binarywang.wx.miniapp.api.impl; | ||||
|  | ||||
| import org.apache.commons.codec.digest.DigestUtils; | ||||
|  | ||||
| import cn.binarywang.wx.miniapp.api.WxMaService; | ||||
| import cn.binarywang.wx.miniapp.api.WxMaUserService; | ||||
| import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; | ||||
| import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; | ||||
| import cn.binarywang.wx.miniapp.bean.WxMaUserInfo; | ||||
| import cn.binarywang.wx.miniapp.config.WxMaConfig; | ||||
| import cn.binarywang.wx.miniapp.util.crypt.WxMaCryptUtils; | ||||
| import com.google.gson.JsonArray; | ||||
| import com.google.gson.JsonObject; | ||||
| import me.chanjar.weixin.common.error.WxError; | ||||
| import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import me.chanjar.weixin.common.util.SignUtils; | ||||
| import org.apache.commons.codec.binary.Hex; | ||||
| import org.apache.commons.codec.digest.DigestUtils; | ||||
|  | ||||
| import javax.crypto.Mac; | ||||
| import javax.crypto.spec.SecretKeySpec; | ||||
| import java.security.InvalidKeyException; | ||||
| import java.security.NoSuchAlgorithmException; | ||||
| import java.util.Map; | ||||
|  | ||||
| /** | ||||
|  * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||
| @ -30,6 +41,30 @@ public class WxMaUserServiceImpl implements WxMaUserService { | ||||
|     return WxMaUserInfo.fromJson(WxMaCryptUtils.decrypt(sessionKey, encryptedData, ivStr)); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public void setUserStorage(Map<String, String> kvMap, String sessionKey, String openid) throws WxErrorException { | ||||
|     final WxMaConfig config = this.service.getWxMaConfig(); | ||||
|     JsonObject param = new JsonObject(); | ||||
|     JsonArray array = new JsonArray(); | ||||
|     for (Map.Entry<String, String> e : kvMap.entrySet()) { | ||||
|       JsonObject jsonObject = new JsonObject(); | ||||
|       jsonObject.addProperty("key", e.getKey()); | ||||
|       jsonObject.addProperty("value", e.getValue()); | ||||
|       array.add(jsonObject); | ||||
|     } | ||||
|     param.add("kv_list", array); | ||||
|     String params = param.toString(); | ||||
|     String signature = SignUtils.createHmacSha256Sign(params, sessionKey); | ||||
|     String url = String.format("https://api.weixin.qq.com/wxa/set_user_storage" + | ||||
|         "?appid=%s&signature=%s&openid=%s&sig_method=%s", | ||||
|       config.getAppid(), signature, openid, "hmac_sha256"); | ||||
|     String result = this.service.post(url, params); | ||||
|     WxError error = WxError.fromJson(result); | ||||
|     if (error.getErrorCode() != 0) { | ||||
|       throw new WxErrorException(error); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public WxMaPhoneNumberInfo getPhoneNoInfo(String sessionKey, String encryptedData, String ivStr) { | ||||
|     return WxMaPhoneNumberInfo.fromJson(WxMaCryptUtils.decrypt(sessionKey, encryptedData, ivStr)); | ||||
|  | ||||
| @ -1,5 +1,9 @@ | ||||
| package cn.binarywang.wx.miniapp.api.impl; | ||||
|  | ||||
| import cn.binarywang.wx.miniapp.test.TestConfig; | ||||
| import com.google.common.collect.ImmutableMap; | ||||
| import jdk.nashorn.internal.ir.annotations.Immutable; | ||||
| import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import org.testng.annotations.*; | ||||
|  | ||||
| import cn.binarywang.wx.miniapp.api.WxMaService; | ||||
| @ -8,6 +12,8 @@ import cn.binarywang.wx.miniapp.bean.WxMaUserInfo; | ||||
| import cn.binarywang.wx.miniapp.test.ApiTestModule; | ||||
| import com.google.inject.Inject; | ||||
|  | ||||
| import javax.management.ImmutableDescriptor; | ||||
|  | ||||
| import static org.testng.Assert.*; | ||||
|  | ||||
| /** | ||||
| @ -54,4 +60,17 @@ public class WxMaUserServiceImplTest { | ||||
|     assertNotNull(phoneNoInfo); | ||||
|     System.out.println(phoneNoInfo.toString()); | ||||
|   } | ||||
|  | ||||
|   @Test | ||||
|   public void testGetSessionInfo() { | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    *  TODO 测试数据有问题,需要替换为正确的数据 | ||||
|    */ | ||||
|   @Test | ||||
|   public void testSetUserStorage() throws WxErrorException { | ||||
|     this.wxService.getUserService().setUserStorage(ImmutableMap.of("1","2"), | ||||
|       "r7BXXKkLb8qrSNn05n0qiA",((TestConfig)this.wxService.getWxMaConfig()).getOpenid()); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -6,19 +6,12 @@ import com.github.binarywang.wxpay.constant.WxPayConstants.SignType; | ||||
| import com.google.common.collect.Lists; | ||||
| import com.google.common.collect.Maps; | ||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
| import me.chanjar.weixin.common.util.BeanUtils; | ||||
| import org.apache.commons.codec.binary.Hex; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.apache.commons.codec.digest.DigestUtils; | ||||
| import org.apache.commons.lang3.StringUtils; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
|  | ||||
| import javax.crypto.Mac; | ||||
| import javax.crypto.spec.SecretKeySpec; | ||||
| import java.lang.reflect.Field; | ||||
| import java.lang.reflect.Modifier; | ||||
| import java.security.InvalidKeyException; | ||||
| import java.security.NoSuchAlgorithmException; | ||||
| import java.util.*; | ||||
|  | ||||
| /** | ||||
| @ -29,9 +22,8 @@ import java.util.*; | ||||
|  * | ||||
|  * @author <a href="https://github.com/binarywang">binarywang(Binary Wang)</a> | ||||
|  */ | ||||
| @Slf4j | ||||
| public class SignUtils { | ||||
|   private static final Logger log = LoggerFactory.getLogger(SignUtils.class); | ||||
|  | ||||
|   /** | ||||
|    * 请参考并使用 {@link #createSign(Object, String, String, boolean)}. | ||||
|    */ | ||||
| @ -91,26 +83,12 @@ public class SignUtils { | ||||
|  | ||||
|     toSign.append("key=").append(signKey); | ||||
|     if (SignType.HMAC_SHA256.equals(signType)) { | ||||
|       return createHmacSha256Sign(toSign.toString(), signKey); | ||||
|       return me.chanjar.weixin.common.util.SignUtils.createHmacSha256Sign(toSign.toString(), signKey); | ||||
|     } else { | ||||
|       return DigestUtils.md5Hex(toSign.toString()).toUpperCase(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   private static String createHmacSha256Sign(String message, String key) { | ||||
|     try { | ||||
|       Mac sha256 = Mac.getInstance("HmacSHA256"); | ||||
|       SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "HmacSHA256"); | ||||
|       sha256.init(secretKeySpec); | ||||
|       byte[] bytes = sha256.doFinal(message.getBytes()); | ||||
|       return Hex.encodeHexString(bytes).toUpperCase(); | ||||
|     } catch (NoSuchAlgorithmException | InvalidKeyException e) { | ||||
|       log.error(e.getMessage(), e); | ||||
|     } | ||||
|  | ||||
|     return null; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 校验签名是否正确. | ||||
|    * | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Binary Wang
					Binary Wang