com.gitlab.summercattle.addons.wechat.miniprogram.service.impl.MiniProgramServiceImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cattle-addons-wechat-starter Show documentation
Show all versions of cattle-addons-wechat-starter Show documentation
Cattle Framework Addons WeChat Component
The newest version!
/*
* Copyright (C) 2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.gitlab.summercattle.addons.wechat.miniprogram.service.impl;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.gitlab.summercattle.addons.wechat.auth.service.UserService;
import com.gitlab.summercattle.addons.wechat.bind.BindUserInfo;
import com.gitlab.summercattle.addons.wechat.common.AppType;
import com.gitlab.summercattle.addons.wechat.common.MiniProgramUserSession;
import com.gitlab.summercattle.addons.wechat.common.AbstractUserSession;
import com.gitlab.summercattle.addons.wechat.common.service.WeChatService;
import com.gitlab.summercattle.addons.wechat.constants.WeChatConstants;
import com.gitlab.summercattle.addons.wechat.memory.SessionMemoryService;
import com.gitlab.summercattle.addons.wechat.miniprogram.bind.UserPhoneNumberBindHandle;
import com.gitlab.summercattle.addons.wechat.miniprogram.configure.MiniProgramConfigProperties;
import com.gitlab.summercattle.addons.wechat.miniprogram.configure.MiniProgramApplication;
import com.gitlab.summercattle.addons.wechat.miniprogram.service.MiniProgramService;
import com.gitlab.summercattle.addons.wechat.miniprogram.service.UserEncryptKeyInfo;
import com.gitlab.summercattle.addons.wechat.store.UserBindInfo;
import com.gitlab.summercattle.addons.wechat.store.UserBindStoreService;
import com.gitlab.summercattle.addons.wechat.utils.ApplicationUtils;
import com.gitlab.summercattle.addons.wechat.utils.SignUtils;
import com.gitlab.summercattle.commons.exception.CommonException;
import com.gitlab.summercattle.commons.utils.auxiliary.UuidUtils;
import com.gitlab.summercattle.commons.utils.reflect.ClassType;
import com.gitlab.summercattle.commons.utils.reflect.ReflectUtils;
import com.gitlab.summercattle.commons.utils.spring.RestTemplateUtils;
/**
* 微信小程序服务实现
* @author orange
*
*/
@Service
public class MiniProgramServiceImpl implements MiniProgramService {
private static final Logger logger = LoggerFactory.getLogger(MiniProgramServiceImpl.class);
@Autowired
private MiniProgramConfigProperties miniProgramConfigProperties;
@Autowired
@Qualifier(WeChatConstants.REST_TEMPLATE_UTILS_NAME)
private RestTemplateUtils restTemplateUtils;
@Autowired
private WeChatService weChatService;
@Autowired
private UserService userService;
@Autowired(required = false)
private UserPhoneNumberBindHandle userPhoneNumberBindHandle;
@Autowired
private UserBindStoreService userBindStoreService;
@Autowired
private SessionMemoryService sessionMemoryService;
@Override
public MiniProgramUserSession getSession(String source, String jsCode) throws CommonException {
MiniProgramApplication miniProgramApplication = ApplicationUtils.getMiniProgramApplication(source, miniProgramConfigProperties);
if (StringUtils.isBlank(jsCode)) {
throw new CommonException("临时登录凭证为空");
}
String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + miniProgramApplication.getAppId() + "&secret="
+ miniProgramApplication.getSecret() + "&js_code=" + jsCode + "&grant_type=authorization_code";
logger.debug("微信小程序的会话请求地址:" + url);
String strJson = restTemplateUtils.get(url, null, null, String.class);
logger.debug("微信小程序的临时登录凭证:" + jsCode + ",返回:" + strJson);
JSONObject respJson = JSON.parseObject(strJson);
boolean isErrMsg = respJson.containsKey("errmsg");
if (isErrMsg) {
throw new CommonException("微信小程序登录接口异常,错误码:" + ((String) ReflectUtils.convertValue(ClassType.String, respJson.getIntValue("errcode")))
+ ",错误信息:" + respJson.getString("errmsg"));
}
String openId = respJson.getString("openid");
String unionId = respJson.getString("unionid");
String sessionKey = respJson.getString("session_key");
UserBindInfo userBindInfo = userBindStoreService.getUserBindInfo(source, AppType.MiniProgram, openId, unionId);
String sessionId = UuidUtils.getUuid();
long sessionTimeout = 0;
MiniProgramUserSession session = null;
if (userBindInfo != null) {
session = new MiniProgramUserSession(sessionId, openId, unionId, sessionKey, userBindInfo.getId(), userBindInfo.getUserType(),
userBindInfo.getInfo());
sessionTimeout = miniProgramConfigProperties.getSessionTimeout();
}
else {
session = new MiniProgramUserSession(sessionId, openId, unionId, sessionKey);
sessionTimeout = miniProgramConfigProperties.getTemporarySessionTimeout();
}
sessionMemoryService.save(source, session, sessionTimeout);
return session;
}
@Override
public void bind(String source, String sessionId, String code, Map parameters) throws CommonException {
AbstractUserSession session = userService.getSession(source, sessionId);
if (AppType.MiniProgram != session.getType()) {
throw new CommonException("应用类型'" + session.getType().toString() + "'不支持");
}
String accessToken = weChatService.getAccessToken(AppType.MiniProgram, source);
if (StringUtils.isBlank(accessToken)) {
throw new CommonException("微信小程序访问令牌为空");
}
if (StringUtils.isBlank(code)) {
throw new CommonException("手机号获取凭证为空");
}
JSONObject requestJson = new JSONObject();
requestJson.put("code", code);
String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken;
logger.debug("用于将code换取用户手机号接口,地址:" + url + ",请求Json:" + requestJson.toString());
JSONObject resultJson = restTemplateUtils.post(url, MediaType.APPLICATION_JSON, null, requestJson, JSONObject.class);
logger.debug("用于将code换取用户手机号接口,返回Json:" + resultJson.toString());
int errcode = resultJson.getIntValue("errcode");
if (errcode != 0) {
throw new CommonException("用于将code换取用户手机号接口异常,错误码:" + resultJson.getIntValue("errcode") + ",错误信息:" + resultJson.getString("errmsg"));
}
String phoneNumber = resultJson.getJSONObject("phone_info").getString("phoneNumber");
if (userPhoneNumberBindHandle == null) {
throw new CommonException("用户手机号绑定处理为空");
}
BindUserInfo bindUserInfo = userPhoneNumberBindHandle.process(phoneNumber, parameters);
if (bindUserInfo == null) {
if (userPhoneNumberBindHandle.isAutoCreated(parameters)) {
bindUserInfo = userPhoneNumberBindHandle.create(phoneNumber, parameters);
}
else {
throw new CommonException("用户绑定失败");
}
}
if (bindUserInfo == null) {
throw new CommonException("绑定用户信息为空");
}
if (bindUserInfo.getUserType() == 0) {
throw new CommonException("用户类型没有设置");
}
if (StringUtils.isBlank(bindUserInfo.getInfo())) {
throw new CommonException("绑定信息为空");
}
String bindId = userBindStoreService.save(source, AppType.MiniProgram, session.getOpenId(), session.getUnionId(), bindUserInfo.getUserType(),
bindUserInfo.getInfo());
sessionMemoryService.invalid(source, sessionId);
session.setBindUser(true);
session.setBindId(bindId);
session.setUserType(bindUserInfo.getUserType());
session.setBindInfo(bindUserInfo.getInfo());
int sessionTimeout = miniProgramConfigProperties.getSessionTimeout();
sessionMemoryService.save(source, session, sessionTimeout);
}
@Override
public List getUserEncryptKeys(String source, String sessionId) throws CommonException {
AbstractUserSession session = userService.getSession(source, sessionId);
if (AppType.MiniProgram != session.getType()) {
throw new CommonException("应用类型'" + session.getType().toString() + "'不支持");
}
MiniProgramUserSession userSession = (MiniProgramUserSession) session;
String accessToken = weChatService.getAccessToken(AppType.MiniProgram, source);
if (StringUtils.isBlank(accessToken)) {
throw new CommonException("微信小程序访问令牌为空");
}
String signature = SignUtils.signSha256Hmac(userSession.getSessionKey(), "");
String url = "https://api.weixin.qq.com/wxa/business/getuserencryptkey?access_token=" + accessToken + "&openid=" + userSession.getOpenId()
+ "&signature=" + signature + "" + "&sig_method=hmac_sha256";
logger.debug("查询用户加密要素信息接口,地址:" + url);
JSONObject resultJson = restTemplateUtils.post(url, MediaType.APPLICATION_JSON, null, null, JSONObject.class);
logger.debug("查询用户加密要素信息接口,返回Json:" + resultJson.toString());
int errcode = resultJson.getIntValue("errcode");
if (errcode != 0) {
throw new CommonException("查询用户加密要素信息接口异常,错误码:" + resultJson.getIntValue("errcode") + ",错误信息:" + resultJson.getString("errmsg"));
}
List userEncryptKeyInfos = new Vector();
JSONArray keyInfoArray = resultJson.getJSONArray("key_info_list");
for (int i = 0; i < keyInfoArray.size(); i++) {
JSONObject keyInfoJson = keyInfoArray.getJSONObject(i);
userEncryptKeyInfos.add(new UserEncryptKeyInfo(keyInfoJson.getString("encrypt_key"), keyInfoJson.getIntValue("version"),
keyInfoJson.getIntValue("expire_in"), keyInfoJson.getString("iv"), new Date(keyInfoJson.getLongValue("create_time") * 1000L)));
}
return userEncryptKeyInfos;
}
@Override
public boolean checkSessionKey(String source, String sessionId) throws CommonException {
AbstractUserSession session = userService.getSession(source, sessionId);
if (AppType.MiniProgram != session.getType()) {
throw new CommonException("应用类型'" + session.getType().toString() + "'不支持");
}
MiniProgramUserSession userSession = (MiniProgramUserSession) session;
String accessToken = weChatService.getAccessToken(AppType.MiniProgram, source);
if (StringUtils.isBlank(accessToken)) {
throw new CommonException("微信小程序访问令牌为空");
}
String signature = SignUtils.signSha256Hmac(userSession.getSessionKey(), "");
String url = "https://api.weixin.qq.com/wxa/checksession?access_token=" + accessToken + "&signature=" + signature + "&openid="
+ userSession.getOpenId() + "&sig_method=hmac_sha256";
logger.debug("检查Session Key是否有效接口,地址:" + url);
JSONObject resultJson = restTemplateUtils.get(url, MediaType.APPLICATION_JSON, null, JSONObject.class);
logger.debug("检查Session Key是否有效接口,返回Json:" + resultJson.toString());
int errcode = resultJson.getIntValue("errcode");
return errcode == 0;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy