三、application.yml 配置cn.hutool hutool-all5.4.0 compile org.bouncycastle bcprov-jdk15on1.56 compile
wechat: appId: ******** appSecret: *******四、工具类
WeChatUtil工具
package com.prison.common.util;
import cn.hutool.core.codec.base64;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.AlgorithmParameters;
import java.security.Security;
import java.util.Arrays;
import java.util.HashMap;
public class WeChatUtil {
public final static String jsCode2SessionUrl = "https://api.weixin.qq.com/sns/jscode2session";
public static JSonObject getSessionKeyOrOpenId(String appid, String secret, String code) {
HashMap requestUrlParam = new HashMap<>();
//小程序appId
requestUrlParam.put("appid", appid);
//小程序secret
requestUrlParam.put("secret", secret);
//小程序端返回的code
requestUrlParam.put("js_code", code);
//默认参数
requestUrlParam.put("grant_type", "authorization_code");
//发送post请求读取调用微信接口获取openid用户唯一标识
String result = HttpUtil.get(jsCode2SessionUrl, requestUrlParam);
JSonObject jsonObject = JSONUtil.parseObj(result);
return jsonObject;
}
public static JSonObject getUserInfo(String encryptedData, String sessionKey, String iv) throws Exception {
// 被加密的数据
byte[] dataByte = base64.decode(encryptedData);
// 加密秘钥
byte[] keyByte = base64.decode(sessionKey);
// 偏移量
byte[] ivByte = base64.decode(iv);
// 如果密钥不足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 JSONUtil.parseObj(result);
}
return null;
}
}
微信信息配置类
package com.prison.wechat.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "wechat")
public class WechatInfoConfig {
private String appId;
private String appSecret;
}
五、入参出参
微信 code2session 入参
package com.prison.common.bo.wx;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel("微信 code2session 入参")
@Data
public class WxCode2SessionPBO {
@ApiModelProperty(value = "微信返回的code")
private String code;
@ApiModelProperty(value = "非敏感的用户信息")
private String rawData;
@ApiModelProperty(value = "签名信息")
private String signature;
}
微信code2session 返回值
package com.prison.common.bo.wx;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel("微信code2session 返回值")
@Data
public class WxCode2SessionRBO {
@ApiModelProperty(value = "openid")
private String openid;
@ApiModelProperty(value = "session_key")
private String sessionKey;
}
获取手机号入参
package com.prison.common.bo.wx;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel("获取手机号入参")
@Data
public class WxGetPhonePBO {
@ApiModelProperty(value = "openid")
private String openid;
@ApiModelProperty(value = "session_key")
private String sessionKey;
@ApiModelProperty(value = "加密的数据")
private String encrypteData;
@ApiModelProperty(value = "加密密钥")
private String iv;
}
六、controller
微信 UserController
package com.prison.wechat.controller;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.prison.common.bo.wx.WxCode2SessionPBO;
import com.prison.common.bo.wx.WxCode2SessionRBO;
import com.prison.common.bo.wx.WxGetPhonePBO;
import com.prison.common.entity.Result;
import com.prison.common.enums.ResultType;
import com.prison.common.util.DateUtils;
import com.prison.common.util.IdUtils;
import com.prison.common.util.WeChatUtil;
import com.prison.core.entity.WxUser;
import com.prison.core.service.IWxUserService;
import com.prison.wechat.config.WechatInfoConfig;
import com.sun.org.apache.xml.internal.security.exceptions.base64DecodingException;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/wxUser")
public class WeChatUserController {
@Autowired
IWxUserService wxUserService;
@Autowired
WechatInfoConfig wechatInfoConfig;
@PostMapping("/code2session")
public Result code2session(@RequestBody WxCode2SessionPBO wxCode2SessionPBO) throws base64DecodingException {
//开发者服务器 登录凭证校验接口 appId + appSecret + 接收小程序发送的code
JSonObject SessionKeyOpenId = WeChatUtil.getSessionKeyOrOpenId(wechatInfoConfig.getAppId(),
wechatInfoConfig.getAppSecret(), wxCode2SessionPBO.getCode());
//接收微信接口服务 获取返回的参数
String openid = SessionKeyOpenId.get("openid", String.class);
String sessionKey = SessionKeyOpenId.get("session_key", String.class);
//用户非敏感信息:rawData
//签名:signature
JSonObject rawDataJson = JSONUtil.parseObj(wxCode2SessionPBO.getRawData());
//根据返回的User实体类,判断用户是否是新用户,是的话,将用户信息存到数据库;
WxUser wxUser = wxUserService.selectWxUserByOpenId(openid);
if (wxUser == null ) {
wxUser = new WxUser();
wxUser.setUserNo(IdUtils.getUUID());
wxUser.setNickName(rawDataJson.getStr("nickName"));
wxUser.setAvatarUrl(rawDataJson.getStr("avatarUrl"));
wxUser.setCreateTime(DateUtils.getNowDate());
wxUser.setGender(rawDataJson.getStr("gender"));
wxUser.setCity(rawDataJson.getStr("city"));
wxUser.setCountry(rawDataJson.getStr("country"));
wxUser.setCountry(rawDataJson.getStr("province"));
wxUser.setCity(rawDataJson.getStr("city"));
// 新增用户到数据库
wxUserService.insertWxUser(wxUser);
}
//把新的skey返回给小程序
WxCode2SessionRBO result = new WxCode2SessionRBO();
result.setSessionKey(sessionKey);
result.setOpenid(openid);
return new Result(ResultType.SUCCESS, result);
}
@WxLogInterceptor(source = 1, requestEvent = "获取授权手机号", operationType = 1, requestUrl = "/weChat/getPhoneNumber")
@PostMapping(value = "/getPhoneNumber")
@ApiOperation(value = "获取授权手机号", httpMethod = "POST")
public Result getPhoneNumber(@RequestBody WxGetPhonePBO wxGetPhonePBO) throws Exception {
JSonObject userInfo = WeChatUtil.getUserInfo(wxGetPhonePBO.getEncrypteData(),
wxGetPhonePBO.getSessionKey(), wxGetPhonePBO.getIv());
String phoneNumber = userInfo.getStr("phoneNumber");
WxUser wxUser = new WxUser();
wxUser.setUserNo(WxUserContextHolder.getUser().getUserNo());
wxUser.setPhoneNumber(base64Util.encode(phoneNumber));//手机号加密
wxUser.setPhoneTime(DateUtils.getNowDate());
wxUserService.updateWxUser(wxUser);
wechatDataSyncService.dataSnyc(wxUser.getUserNo());
return new Result(ResultType.SUCCESS, phoneNumber);
}
}
注:以上内容仅提供参考和交流,请勿用于商业用途,如有侵权联系本人删除!



