//小程序 appId
@Value("${wx.miniApp.app_id}")
private String appId;
//小程序 appSecret
@Value("${wx.miniApp.app_secret}")
private String appSecret;
public R getUserInfoMap(WechatLoginRequest loginRequest) throws Exception {
// 调用微信 API 获取用户的 openid 和 session_key
JSONObject sessionKeyOpenId = getSessionKeyOrOpenId(loginRequest.getCode());
String unionid = sessionKeyOpenId.getString("unionid");
String sessionKey = sessionKeyOpenId.getString("session_key");
String openId = sessionKeyOpenId.getString("openid");
//校验签名 小程序发送的签名signature与服务器端生成的签名signature2 = sha1(rawData + sessionKey)
String signature2 = DigestUtils.sha1Hex(loginRequest.getRawData() + sessionKey);
if (!loginRequest.getSignature().equals(signature2)) {
return R.error("签名校验失败");
}
CMember wxMember = cMemberService.getMemberByWechatOpenId(unionid);
String token;
CMember insertOrUpdateDO = null;
String phoneNumber = getPhone(loginRequest.getPhoneNumberCode());
if (wxMember == null) {
// 调用微信 API 获取用户的手机号
// 调用微信 API 获取用户的详细信息
insertOrUpdateDO = buildWechatUserAuthInfoDO(loginRequest, sessionKey, unionid, openId);
//手机号
if (StringUtils.isNotBlank(phoneNumber)) {
insertOrUpdateDO.setPhoneNum(phoneNumber);
}
// 用户不存在,insert用户
insertOrUpdateDO.setId(UUID.get());
cMemberService.save(insertOrUpdateDO);
//生成token并存redis
token = commonService.genCrmToken(insertOrUpdateDO);
} else {
//手机号
if (StringUtils.isNotBlank(phoneNumber)) {
wxMember.setPhoneNum(phoneNumber);
}
wxMember.setWxOpenId(openId);
cMemberService.updateById(wxMember);
//生成token并存redis
token = commonService.genCrmToken(wxMember);
}
Map<String, String> map = new HashMap();
map.put("token", token);
map.put("memberId", wxMember != null ? wxMember.getId() : insertOrUpdateDO.getId());
return R.success(map);
}
/**
* 小程序登录-前端通过code获取微信session信息
*
* @param code 登录时获取的 code,可通过wx.login获取
* param appid appid
* param secret 小程序 appSecret
* param grant_type 授权类型,此处只需填写 authorization_code
* @return errcode 错误码
*/
private JSONObject getSessionKeyOrOpenId(String code) throws Exception {
Map<String, String> requestUrlParam = new HashMap<>();
requestUrlParam.put("appid", appId);
requestUrlParam.put("secret", appSecret);
requestUrlParam.put("js_code", code);
requestUrlParam.put("grant_type", "authorization_code");
// 发送post请求读取调用微信接口获取openid用户唯一标识
String result = HttpClientUtils.doPost("https://api.weixin.qq.com/sns/jscode2session", requestUrlParam);
return JSON.parseObject(result);
}
/**
* 调用微信 API 获取用户的手机号
*
* @param jsCode
* @return
*/
@Override
public String getPhone(String jsCode) {
// 1.请求微信接口服务,获取accessToken
String wechatToken = commonService.getAccessToken();
// 2.请求微信接口服务,获取用户手机号信息
JSONObject phoneNumberJson = getPhoneNumber(jsCode, wechatToken);
WeChatPhoneInfo phoneInfo = JSONObject.toJavaObject(phoneNumberJson.getJSONObject("phone_info"), WeChatPhoneInfo.class);
return phoneInfo.getPurePhoneNumber();
}
/**
* 获取用户基本信息
*
* @param loginRequest
* @param sessionKey
* @param unionid
* @return
*/
private CMember buildWechatUserAuthInfoDO(WechatLoginRequest loginRequest, String sessionKey, String unionid, String openId) {
CMember cMember = new CMember();
cMember.setWxUnionId(unionid);
cMember.setWxOpenId(openId);
log.info("小程序登录信息======================"+loginRequest.getRawData());
if (loginRequest.getRawData() != null) {
RawDataDO rawDataDO = JSON.parseObject(loginRequest.getRawData(), RawDataDO.class);
log.info("小程序登录信息JSON==================="+rawDataDO);
log.info("小程序登录信息性别=================="+rawDataDO.getGender());
cMember.setCreateTime(DateUtils.getCurrentTime());
cMember.setSex(rawDataDO.getGender());
}
cMember.setAvatar(loginRequest.getAvatar());
cMember.setNickName(loginRequest.getNickName());
// 解密加密信息,获取unionID
// if (loginRequest.getEncryptedData() != null){
// JSONObject encryptedData = getEncryptedData(loginRequest.getEncryptedData(), sessionKey, loginRequest.getIv());
// if (encryptedData != null){
// String unionId = encryptedData.getString("unionId");
// cMember.setWxUnionId(unionId);
// }
// }
return cMember;
}
public class HttpClientUtils
{
private static Logger logger = LoggerFactory.getLogger(HttpClientUtils.class); // 日志记录
private static RequestConfig requestConfig = null;
final static int TIMEOUT = 1000;
final static int TIMEOUT_MSEC = 5 * 1000;
static
{
// 设置请求和传输超时时间
requestConfig = RequestConfig.custom().setSocketTimeout(2000).setConnectTimeout(2000).build();
}
/**
* post请求传输json参数
* @param url url地址
* @param
* @return
*/
public static JSONObject httpPost(String url, JSONObject jsonParam)
{
// post请求返回结果
CloseableHttpClient httpClient = HttpClients.createDefault();
JSONObject jsonResult = null;
HttpPost httpPost = new HttpPost(url);
// 设置请求和传输超时时间
httpPost.setConfig(requestConfig);
try
{
if (null != jsonParam)
{
// 解决中文乱码问题
StringEntity entity = new StringEntity(jsonParam.toString(), "utf-8");
entity.setContentEncoding("UTF-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
}
CloseableHttpResponse result = httpClient.execute(httpPost);
// 请求发送成功,并得到响应
if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
{
String str = "";
try
{
// 读取服务器返回过来的json字符串数据
str = EntityUtils.toString(result.getEntity(), "utf-8");
// 把json字符串转换成json对象
jsonResult = JSONObject.parseObject(str);
}
catch (Exception e)
{
logger.error("post请求提交失败:" + url, e);
}
}
}
catch (IOException e)
{
logger.error("post请求提交失败:" + url, e);
}
finally
{
httpPost.releaseConnection();
}
return jsonResult;
}
/**
* post请求传输String参数 例如:name=Jack&sex=1&type=2
* Content-type:application/x-www-form-urlencoded
* @param url url地址
* @param strParam 参数
* @return
*/
public static JSONObject httpPost(String url, String strParam)
{
// post请求返回结果
CloseableHttpClient httpClient = HttpClients.createDefault();
JSONObject jsonResult = null;
HttpPost httpPost = new HttpPost(url);
httpPost.setConfig(requestConfig);
try
{
if (null != strParam)
{
// 解决中文乱码问题
StringEntity entity = new StringEntity(strParam, "utf-8");
entity.setContentEncoding("UTF-8");
entity.setContentType("application/x-www-form-urlencoded");
httpPost.setEntity(entity);
}
CloseableHttpResponse result = httpClient.execute(httpPost);
// 请求发送成功,并得到响应
if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
{
String str = "";
try
{
// 读取服务器返回过来的json字符串数据
str = EntityUtils.toString(result.getEntity(), "utf-8");
// 把json字符串转换成json对象
jsonResult = JSONObject.parseObject(str);
}
catch (Exception e)
{
logger.error("post请求提交失败:" + url, e);
}
}
}
catch (IOException e)
{
logger.error("post请求提交失败:" + url, e);
}
finally
{
httpPost.releaseConnection();
}
return jsonResult;
}
public static String doPost(String url, Map<String, String> paramMap) throws IOException {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
// 创建参数列表
if (paramMap != null) {
List<NameValuePair> paramList = new ArrayList<>();
for (Map.Entry<String, String> param : paramMap.entrySet()) {
paramList.add(new BasicNameValuePair(param.getKey(), param.getValue()));
}
// 模拟表单
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
httpPost.setEntity(entity);
}
httpPost.setConfig(builderRequestConfig());
// 执行http请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
} catch (Exception e) {
throw e;
} finally {
try {
response.close();
} catch (IOException e) {
throw e;
}
}
return resultString;
}
private static RequestConfig builderRequestConfig() {
return RequestConfig.custom()
.setConnectTimeout(TIMEOUT_MSEC)
.setConnectionRequestTimeout(TIMEOUT_MSEC)
.setSocketTimeout(TIMEOUT_MSEC).build();
}
/**
* 发送get请求
* @param url 路径
* @return
*/
public static JSONObject httpGet(String url)
{
// get请求返回结果
JSONObject jsonResult = null;
CloseableHttpClient client = HttpClients.createDefault();
// 发送get请求
HttpGet request = new HttpGet(url);
request.setConfig(requestConfig);
try
{
CloseableHttpResponse response = client.execute(request);
// 请求发送成功,并得到响应
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
{
// 读取服务器返回过来的json字符串数据
HttpEntity entity = response.getEntity();
String strResult = EntityUtils.toString(entity, "utf-8");
// 把json字符串转换成json对象
jsonResult = JSONObject.parseObject(strResult);
}
else
{
logger.error("get请求提交失败:" + url);
}
}
catch (IOException e)
{
logger.error("get请求提交失败:" + url, e);
}
finally
{
request.releaseConnection();
}
return jsonResult;
}
}