1、父子认证实现和关系建立新增

2、电子健康卡用主体id认证通过
debug
王绍全 3 days ago
parent 10f9323c73
commit 07adc6176e
  1. 14
      src/main/java/com/ynxbd/common/action/auth/WxAuthAction.java
  2. 29
      src/main/java/com/ynxbd/common/bean/GMCUser.java
  3. 33
      src/main/java/com/ynxbd/common/dao/GMCUserDao.java
  4. 5
      src/main/java/com/ynxbd/common/helper/common/CodeHelper.java
  5. 4
      src/main/java/com/ynxbd/common/helper/http/OkHttpHelper.java
  6. 19
      src/main/java/com/ynxbd/common/result/JsonResult.java
  7. 5
      src/main/java/com/ynxbd/common/result/JsonResultEnum.java
  8. 23
      src/main/java/com/ynxbd/common/result/Result.java
  9. 31
      src/main/java/com/ynxbd/common/service/GMCUserService.java
  10. 318
      src/main/java/com/ynxbd/wx/wxfactory/WxAuthHelper.java
  11. 31
      src/main/java/com/ynxbd/wx/wxfactory/WxCacheHelper.java
  12. 65
      src/main/java/com/ynxbd/wx/wxfactory/base/auth/models/AuthResultData.java
  13. 20
      src/main/java/com/ynxbd/wx/wxfactory/base/auth/models/AuthTokenData.java

@ -1,8 +1,7 @@
package com.ynxbd.common.action.pay; package com.ynxbd.common.action.auth;
import com.ynxbd.common.action.base.BaseAction; import com.ynxbd.common.action.base.BaseAction;
import com.ynxbd.common.result.Result; import com.ynxbd.common.result.Result;
import com.ynxbd.wx.config.WeChatConfig;
import com.ynxbd.wx.wxfactory.WxAuthHelper; import com.ynxbd.wx.wxfactory.WxAuthHelper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.Action;
@ -15,7 +14,7 @@ public class WxAuthAction extends BaseAction {
@Action("is_auth") @Action("is_auth")
public Result is_auth() throws Exception { public Result is_auth() throws Exception {
return WxAuthHelper.isAuth(request, response, false); return WxAuthHelper.isAuth(request, response);
} }
@Action("u_auth") @Action("u_auth")
@ -30,16 +29,9 @@ public class WxAuthAction extends BaseAction {
return Result.redirect(auth); return Result.redirect(auth);
} }
@Action("is_pay_auth") @Action("is_pay_auth")
public Result is_pay_auth() throws Exception { public Result is_pay_auth() throws Exception {
// 支付使用普通授权 // 支付使用普通授权
return WxAuthHelper.isAuth(request, response, true); return WxAuthHelper.isAuth(request, response);
} }
// @Action("pay_b_auth")
// public Result pay_b_auth() throws Exception {
// String auth = WxAuthHelper.auth(request, response, true, true);
// return Result.redirect(auth);
// }
} }

@ -0,0 +1,29 @@
package com.ynxbd.common.bean;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import java.util.Date;
@Setter
@Getter
@ToString
@NoArgsConstructor
public class GMCUser {
private Long id;
private Date updateTime;
private String wxOpenId;
private String gmcOpenId;
private String gmcUnionId;
private String gmcUUID;
}

@ -0,0 +1,33 @@
package com.ynxbd.common.dao;
import com.ynxbd.common.bean.GMCUser;
import com.ynxbd.common.config.db.DataBase;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class GMCUserDao {
/**
* 查询用户关联关系
*/
public GMCUser selectByOpenId(String wxOpenId) {
String sql = "select * from gmc_user where wxOpenId=?";
return DataBase.selectOne(sql, GMCUser.class, ps -> {
ps.setString(1, wxOpenId);
});
}
/**
* 添加关系
*/
public boolean insert(String wxOpenId, String gmcOpenId, String gmcUnionId, String gmcUUID) {
String sql = "insert into gmc_user(updateTime, wxOpenId, gmcOpenId, gmcUnionId, gmcUUID) values (now(),?,?,?,?)";
return DataBase.insert(sql, ps -> {
ps.setString(1, wxOpenId);
ps.setString(2, gmcOpenId);
ps.setString(3, gmcUnionId);
ps.setString(4, gmcUUID);
}) > 0;
}
}

@ -55,11 +55,8 @@ public class CodeHelper {
} }
public static void main(String[] args) { public static void main(String[] args) {
String outTradeNo = getOutTradeNo(MerchantEnum.WX); System.out.println(UUID.randomUUID());
String bankTransNo = outTradeNo.substring(MerchantEnum.WX.CODE.length());
System.out.println(bankTransNo);
} }
/** /**
* 生成数字验证码 * 生成数字验证码
* *

@ -197,9 +197,7 @@ public class OkHttpHelper {
if (body == null) { if (body == null) {
return null; return null;
} }
String respBody = body.string(); return body.string();
log.info("接口响应数据resp={}", respBody);
return respBody;
} }
} catch (Exception e) { } catch (Exception e) {
ErrorHelper.println(e); ErrorHelper.println(e);

@ -420,6 +420,25 @@ public class JsonResult {
return JsonHelper.decodeBean(data.toString(), clazz); return JsonHelper.decodeBean(data.toString(), clazz);
} }
public <T> List<T> dataMapGetNodeToList(Class<T> clazz) {
return dataMapGetNodeToList(clazz, "data");
}
/**
* 获取DataMap为bean
*
* @param clazz 类型
* @return bean
*/
public <T> List<T> dataMapGetNodeToList(Class<T> clazz, String dataName) {
Object data = this.dataMap.get(dataName);
if (data == null) {
return null;
}
return JsonHelper.decodeList(data.toString(), clazz);
}
/** /**
* 获取DataMap为bean * 获取DataMap为bean
* *

@ -16,6 +16,8 @@ public enum JsonResultEnum {
SYS_ME("[医保]", "return_code", "return_msg", "SUCCESS", "FAIL", String.valueOf(HttpStatus.HTTP_CLIENT_TIMEOUT)), SYS_ME("[医保]", "return_code", "return_msg", "SUCCESS", "FAIL", String.valueOf(HttpStatus.HTTP_CLIENT_TIMEOUT)),
SYS_MICRO("[微官网]", "code", "message", "200", "0", String.valueOf(HttpStatus.HTTP_CLIENT_TIMEOUT)),
SYS_MEDICAL_ASSISTANT("[就医助手]", "errcode", "errmsg", "0", "-1", String.valueOf(HttpStatus.HTTP_CLIENT_TIMEOUT)), SYS_MEDICAL_ASSISTANT("[就医助手]", "errcode", "errmsg", "0", "-1", String.valueOf(HttpStatus.HTTP_CLIENT_TIMEOUT)),
SYS_HIS("[HIS]", "ResponseCode", "ResponseMessage", "0", "-1", "500"), SYS_HIS("[HIS]", "ResponseCode", "ResponseMessage", "0", "-1", "500"),
@ -24,8 +26,7 @@ public enum JsonResultEnum {
SYS_RM_LIS("[瑞美LIS]", "ResultCode", "ResultMessage", "1", "0", String.valueOf(HttpStatus.HTTP_CLIENT_TIMEOUT)), SYS_RM_LIS("[瑞美LIS]", "ResultCode", "ResultMessage", "1", "0", String.valueOf(HttpStatus.HTTP_CLIENT_TIMEOUT)),
SYS_PEIS_RESERVE("[体检预约]", "code", "message", "200", "0", String.valueOf(HttpStatus.HTTP_CLIENT_TIMEOUT)) SYS_PEIS_RESERVE("[体检预约]", "code", "message", "200", "0", String.valueOf(HttpStatus.HTTP_CLIENT_TIMEOUT));
;
// 调用系统标识 // 调用系统标识
public final String SYS; public final String SYS;

@ -1,5 +1,6 @@
package com.ynxbd.common.result; package com.ynxbd.common.result;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.ynxbd.common.helper.common.DateHelper; import com.ynxbd.common.helper.common.DateHelper;
@ -12,7 +13,6 @@ import lombok.ToString;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import java.time.LocalDate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -27,8 +27,6 @@ import java.util.Map;
public class Result extends BaseResult { public class Result extends BaseResult {
private static final long serialVersionUID = -1005L; private static final long serialVersionUID = -1005L;
//
private Integer code; private Integer code;
private String message; private String message;
private Object data; private Object data;
@ -192,5 +190,24 @@ public class Result extends BaseResult {
this.date = DateHelper.getCurDateTime(); this.date = DateHelper.getCurDateTime();
} }
public String toDataStr(){
if (data == null) return null;
return data.toString();
}
public <T> T dataToBean(Class<T> clazz) {
if(this.data == null) return null;
return JsonHelper.parseObject(JsonHelper.toJsonString(this.data), clazz);
}
public <T> List<T> dataToList(Class<T> clazz) {
if(this.data == null) return new ArrayList<>();
return JsonHelper.parseArray(JsonHelper.toJsonString(this.data), clazz);
}
public JSONObject dataToBean() {
return JsonHelper.parseObject(JsonHelper.toJsonString(this.data));
}
} }

@ -0,0 +1,31 @@
package com.ynxbd.common.service;
import com.ynxbd.common.bean.GMCUser;
import com.ynxbd.common.dao.GMCUserDao;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
@Slf4j
public class GMCUserService {
/**
* 查询用户关联关系
*/
public GMCUser queryInfoByOpenId(String wxOpenId) {
return new GMCUserDao().selectByOpenId(wxOpenId);
}
/**
* 添加用户关系
*/
public boolean addInfo(String wxOpenId, String gmcOpenId, String gmcUnionId, String gmcUUID) {
try {
if (ObjectUtils.isEmpty(wxOpenId) || ObjectUtils.isEmpty(gmcOpenId) || ObjectUtils.isEmpty(gmcUUID)) {
return false;
}
return new GMCUserDao().insert(wxOpenId, gmcOpenId, gmcUnionId, gmcUUID);
} catch (Exception e) {
return false;
}
}
}

@ -1,13 +1,18 @@
package com.ynxbd.wx.wxfactory; package com.ynxbd.wx.wxfactory;
import com.ynxbd.common.bean.GMCUser;
import com.ynxbd.common.bean.Patient; import com.ynxbd.common.bean.Patient;
import com.ynxbd.common.bean.User; import com.ynxbd.common.bean.User;
import com.ynxbd.common.helper.common.*; import com.ynxbd.common.helper.common.*;
import com.ynxbd.common.helper.http.OkHttpHelper; import com.ynxbd.common.helper.http.OkHttpHelper;
import com.ynxbd.common.result.JsonResult;
import com.ynxbd.common.result.JsonResultEnum;
import com.ynxbd.common.result.Result; import com.ynxbd.common.result.Result;
import com.ynxbd.common.service.GMCUserService;
import com.ynxbd.common.service.PatientService; import com.ynxbd.common.service.PatientService;
import com.ynxbd.wx.config.WeChatConfig; import com.ynxbd.wx.config.WeChatConfig;
import com.ynxbd.wx.wxfactory.base.auth.models.AuthData; import com.ynxbd.wx.wxfactory.base.auth.models.AuthResultData;
import com.ynxbd.wx.wxfactory.base.auth.models.AuthTokenData;
import com.ynxbd.wx.wxfactory.base.auth.models.SnsOath2AccessToken; import com.ynxbd.wx.wxfactory.base.auth.models.SnsOath2AccessToken;
import com.ynxbd.wx.wxfactory.base.auth.models.SnsUserInfo; import com.ynxbd.wx.wxfactory.base.auth.models.SnsUserInfo;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -19,7 +24,10 @@ import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.*; import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j @Slf4j
public class WxAuthHelper { public class WxAuthHelper {
@ -29,47 +37,35 @@ public class WxAuthHelper {
private static final String P_SUFFIX = ":"; // 后缀 private static final String P_SUFFIX = ":"; // 后缀
private static final String AUTH_SESSION_ID_NAME = "SID"; private static final String AUTH_SESSION_ID_NAME = "SID";
private static final String UNION_ID_NAME = "UID"; private static final String GMC_ID = "GMCId";
private static final String OPENID = "openid";
public static String auth(HttpServletRequest request, HttpServletResponse response, boolean isUserInfo) { public static String auth(HttpServletRequest request, HttpServletResponse response, boolean isUserInfo) {
try {
String code = request.getParameter("code"); String code = request.getParameter("code");
String state = request.getParameter("state"); // base64 String state = request.getParameter("state"); // base64
Map<String, String> paramsMap = getParamsMap(request.getParameter("p")); Map<String, String> paramsMap = getParamsMap(request.getParameter("p"));
log.info("[授权] code={}, state={}, paramsMap={}", code, state, JsonHelper.toJsonString(paramsMap)); log.info("[认证授权] code={}, state={}, paramsMap={}", code, state, JsonHelper.toJsonString(paramsMap));
try {
state = state == null ? "" : URLDecoder.decode(Base64Helper.decode(state), "UTF-8"); state = state == null ? "" : URLDecoder.decode(Base64Helper.decode(state), "UTF-8");
String enUnionId = paramsMap.get(UNION_ID_NAME); String authSessionId = AesWxHelper.decode(paramsMap.get(AUTH_SESSION_ID_NAME));
String enAuthSessionId = paramsMap.get(AUTH_SESSION_ID_NAME);
String authSessionId = AesWxHelper.decode(enAuthSessionId); log.info("[认证授权-解码] authSessionId={}, state={}", authSessionId, state);
paramsMap.get(AUTH_SESSION_ID_NAME);
// if (!ObjectUtils.isEmpty(params)) {
// int index = params.indexOf("@" + AUTH_SESSION_ID_NAME + ":");
// if (index == -1) index = params.indexOf("%40" + AUTH_SESSION_ID_NAME + ":"); // 防止数据转义失败
// if (index != -1) {
// enUnionId = params.substring(0, index);
// authSessionId = params.substring(index);
// authSessionId = AesWxHelper.decode(authSessionId);
// }
// }
log.info("[授权-解码] enUnionId={}, enAuthSessionId={}, authSessionId={}, state={}", enUnionId, enAuthSessionId, authSessionId, state);
SnsOath2AccessToken snsToken = WxFactory.Base.OAuth().oauth2AccessToken(WeChatConfig.APP_ID, WeChatConfig.APP_SECRET, code); SnsOath2AccessToken snsToken = WxFactory.Base.OAuth().oauth2AccessToken(WeChatConfig.APP_ID, WeChatConfig.APP_SECRET, code);
log.info("[授权-用户]snsToken={}", JsonHelper.toJsonString(snsToken)); log.info("[认证授权]信息 snsToken={}", JsonHelper.toJsonString(snsToken));
if (snsToken != null) { if (snsToken != null) {
String openid = snsToken.getOpenid(); String openid = snsToken.getOpenid();
String unionId = snsToken.getUnionid(); String unionId = snsToken.getUnionid();
if (unionId == null) {
log.info("[测试] enUnionId={}", enUnionId);
}
if (openid != null) { if (openid != null) {
HttpSession session = request.getSession(); HttpSession session = request.getSession();
session.setMaxInactiveInterval(SESSION_MAX_INACTIVE_INTERVAL); session.setMaxInactiveInterval(SESSION_MAX_INACTIVE_INTERVAL);
session.setAttribute("openid", openid); session.setAttribute(OPENID, openid);
WxCacheHelper.putOpenIdToAIDCache(authSessionId, openid);
WxCacheHelper.putOpenIdCacheToSessionIdCache(authSessionId, openid);
Cache<String, User> cache = WxCacheHelper.getUserCacheManager(); Cache<String, User> cache = WxCacheHelper.getUserCacheManager();
if (WeChatConfig.isDevUser(openid) || !cache.containsKey(openid)) { if (WeChatConfig.isDevUser(openid) || !cache.containsKey(openid)) {
@ -108,7 +104,6 @@ public class WxAuthHelper {
} }
} }
if (WeChatConfig.HAS_HTTPS_BY_BASE_URL) { // 强制为https if (WeChatConfig.HAS_HTTPS_BY_BASE_URL) { // 强制为https
String httpsURL = URLHelper.URLToHttps(state); String httpsURL = URLHelper.URLToHttps(state);
state = httpsURL == null ? "" : httpsURL; state = httpsURL == null ? "" : httpsURL;
@ -130,126 +125,243 @@ public class WxAuthHelper {
} }
public static Result isAuth(HttpServletRequest request, HttpServletResponse response, boolean isPayOAuth) throws Exception { public static Result isAuth(HttpServletRequest request, HttpServletResponse response) throws Exception {
String token = request.getParameter("token"); // 前端缓存 String token = request.getParameter("token"); // 前端缓存
String state = request.getParameter("state"); String state = request.getParameter("state");
String isUserInfo = request.getParameter("isUserInfo"); String isUserInfo = request.getParameter("isUserInfo");
String UID = ParamHelper.filterParamNull(request.getParameter(UNION_ID_NAME), "");
String deState = URLDecoder.decode(Base64Helper.decode(state), "UTF-8"); String deState = URLDecoder.decode(Base64Helper.decode(state), "UTF-8");
HttpSession session = request.getSession();
session.setMaxInactiveInterval(SESSION_MAX_INACTIVE_INTERVAL);
Object sessionOpenIdObj = session.getAttribute(OPENID); // 自身openid
String sessionOpenId = sessionOpenIdObj == null ? null : sessionOpenIdObj.toString();
AuthTokenData authTokenData = new AuthTokenData();
String cacheTokenOpenId = authTokenData.decodeToken(token, WeChatConfig.APP_ID);
log.warn("[授权is_auth] token={}, state={}, isUserInfo={}, deState={}", token, state, isUserInfo, deState);
String authSessionId = null; String authSessionId = null;
if (WeChatConfig.IS_ENABLE_GMC && WeChatConfig.IS_GMC_SERVER && !isPayOAuth) { // 开启医共体开关 & 是医共体主服务器 & 不是支付授权 if (WeChatConfig.IS_ENABLE_GMC) { // 开启医共体开关 & 是医共体主服务器 & 不是支付授权
try {
if (WeChatConfig.IS_GMC_SERVER) {
authSessionId = AesWxHelper.decode(request.getHeader(AUTH_SESSION_ID_NAME)); authSessionId = AesWxHelper.decode(request.getHeader(AUTH_SESSION_ID_NAME));
}
log.warn("[授权is_auth] token={}, state={}, isUserInfo={}, authSessionId={}, UID={}, deState={}", token, state, isUserInfo, authSessionId, UID, deState); } else { // 请求转发
if (WeChatConfig.IS_ENABLE_GMC && !WeChatConfig.IS_GMC_SERVER && !isPayOAuth) { // 开启医共体开关 & 不是医共体主服务器 & 不是支付授权
try { // 请求转发
String serverDomain = WeChatConfig.getDomain(false, false); String serverDomain = WeChatConfig.getDomain(false, false);
if (deState != null && serverDomain != null && !deState.contains(serverDomain)) { if (deState != null && serverDomain != null && !deState.contains(serverDomain)) {
return Result.error("授权域名不匹配"); return Result.error("授权域名不匹配");
} }
return gmc_server_auth(request, session, state, isUserInfo, cacheTokenOpenId, token, authTokenData, sessionOpenId, authSessionId);
}
} catch (Exception e) {
ErrorHelper.println(e);
return Result.error(e);
}
}
HttpSession session = request.getSession(); if (cacheTokenOpenId != null) {
String sessionId = session.getId(); log.info("[微信token认证] token={}, cacheOpenId={}", token, cacheTokenOpenId);
AuthResultData authResultData = getTokenData(cacheTokenOpenId, token, authTokenData);
return Result.success(authResultData.toResultData());
}
log.info("[微信认证]获取 openid={}, authSessionId={}", sessionOpenId, authSessionId);
if (!ObjectUtils.isEmpty(authSessionId) && ObjectUtils.isEmpty(sessionOpenId)) {
sessionOpenId = WxCacheHelper.findOpenIdBySessionIdCache(authSessionId);
log.info("[微信AID认证]sessionOpenId={}", sessionOpenId);
}
AuthResultData authResultData = getCacheUserData(request, sessionOpenId, state, isUserInfo, authSessionId);
if (authResultData.hasAuthUrl()) {
return Result.success(authResultData.getAuthUrl());
}
return Result.success(authResultData.toResultData());
}
log.info("[认证请求转发] [sessionId:{}]URL:[{}]", sessionId, WeChatConfig.getGMCAuthDomain(isHttpsWithProxy(request), true)); /**
String data = OkHttpHelper.postFormStr(WeChatConfig.getGMCAuthDomain(isHttpsWithProxy(request), true) + "wx_auth/is_auth", params -> { * 主体服务器认证
*/
public static Result gmc_server_auth(HttpServletRequest request, HttpSession session, String state, String isUserInfo,
String cacheTokenOpenId, String token, AuthTokenData tokenData, String sessionOpenId, String authSessionId) {
String reqGMCDomain = WeChatConfig.getGMCAuthDomain(isHttpsWithProxy(request), true); // 医共体请求服务地址
// 自身认证
boolean hasTokenCache = !ObjectUtils.isEmpty(cacheTokenOpenId);
String openId = hasTokenCache ? cacheTokenOpenId : sessionOpenId;
if (ObjectUtils.isEmpty(openId)) { // 自身认证未完成
return Result.success(getAuthUrl(request, state, false, null, authSessionId));
}
// log.info("cacheTokenOpenId={}, sessionOpenId={}", cacheTokenOpenId, sessionOpenId);
// 判断是否有主体id
Object sessionGmcOpenId = session.getAttribute(GMC_ID);
String gmcOpenId = sessionGmcOpenId == null ? null : sessionGmcOpenId.toString();
if (gmcOpenId == null) {
GMCUser gmcUser = new GMCUserService().queryInfoByOpenId(openId);
if (gmcUser != null) {
gmcOpenId = gmcUser.getGmcOpenId();
}
}
if (!ObjectUtils.isEmpty(gmcOpenId)) {
if (sessionGmcOpenId == null) {
session.setAttribute(GMC_ID, gmcOpenId);
}
// 查询返回数据
AuthResultData authResultData = null;
if (hasTokenCache) {
authResultData = getTokenData(openId, token, tokenData);
}
if (authResultData == null) {
authResultData = getCacheUserData(request, sessionOpenId, state, isUserInfo, authSessionId);
}
if (authResultData.hasAuthUrl()) { // 授权链接
return Result.success(authResultData.getAuthUrl());
}
// repeatPatients(reqGMCDomain, authResultData.getPatientList(), gmcOpenId); // 患者信息去重
return Result.success(authResultData.toResultData());
}
String sessionId = session.getId();
log.info("[认证请求转发] [sessionId:{}]URL:[{}]", sessionId, reqGMCDomain);
String resultJson = OkHttpHelper.postFormStr(reqGMCDomain + "wx_auth/is_auth", params -> {
params.put("token", token); params.put("token", token);
params.put("state", state); params.put("state", state);
params.put("isUserInfo", isUserInfo); params.put("isUserInfo", "false");
params.put(UNION_ID_NAME, UID);
}, headers -> { }, headers -> {
if (!ObjectUtils.isEmpty(sessionId)) { if (!ObjectUtils.isEmpty(sessionId)) {
headers.add(AUTH_SESSION_ID_NAME, AesWxHelper.encode(WeChatConfig.APP_ID + ":" + sessionId)); headers.add(AUTH_SESSION_ID_NAME, AesWxHelper.encode(WeChatConfig.APP_ID + ":" + sessionId));
} }
}); });
Result result = Result.dataToResult(data, true); Result result = Result.dataToResult(resultJson, true);
System.out.println(JsonHelper.toJsonString(result)); if (!result.isOK()) {
return Result.dataToResult(data, true); return result;
} catch (Exception e) { }
e.printStackTrace(); String dataStr = result.toDataStr();
return Result.error(e); if (dataStr != null && !dataStr.contains("{")) {
return Result.success(dataStr);
}
AuthResultData gmcAuthResultData = result.dataToBean(AuthResultData.class); // 医共体医生
String enGmcOpenId = gmcAuthResultData.getEnOpenId();
gmcOpenId = AesWxHelper.decode(enGmcOpenId); // 主体openid
String gmcUUID = AesWxHelper.decode(gmcAuthResultData.getEnGmcUUID());
if (!ObjectUtils.isEmpty(gmcOpenId)) { // 授权主体完成认证
session.setAttribute(GMC_ID, gmcOpenId);
boolean isOK = new GMCUserService().addInfo(sessionOpenId, gmcOpenId, null, gmcUUID);
log.info("[认证联系]添加{} wxOpenId={}, gmcOpenId={}, gmcUUID={}", (isOK ? "成功" : "失败"), sessionOpenId, gmcOpenId, gmcUUID);
AuthResultData authResultData = getCacheUserData(request, sessionOpenId, state, isUserInfo, authSessionId);
authResultData.setEnGmcOpenId(enGmcOpenId); // 用于绑定传递数据,确保关系记录
return Result.success(authResultData.toResultData());
}
return result;
}
/**
* 从token获取数据
*
* @param cacheOpenId token中的openid
* @param token token
* @param tokenData token解析出来的数据
* @return bean
*/
public static AuthResultData getTokenData(String cacheOpenId, String token, AuthTokenData tokenData) {
if (cacheOpenId == null) {
return null;
} }
if (tokenData == null) {
return null;
} }
log.info("[微信token认证] token={}, cacheOpenId={}", token, cacheOpenId);
boolean isFindUserInfo = ("true".equals(isUserInfo)); User user = WxCacheHelper.getCacheUser(cacheOpenId);
AuthData authData = new AuthData();
String cacheOpenid = authData.decodeToken(token, WeChatConfig.APP_ID);
if (cacheOpenid != null) {
log.info("[微信token认证] token={}, openid={}", token, cacheOpenid);
User user = WxCacheHelper.getCacheUser(cacheOpenid);
List<Patient> patients; List<Patient> patients;
if (user == null) { if (user == null) {
patients = new PatientService().queryPatientList(cacheOpenid, null, true); patients = new PatientService().queryPatientList(cacheOpenId, null, true);
Cache<String, User> cache = WxCacheHelper.getUserCacheManager(); Cache<String, User> cache = WxCacheHelper.getUserCacheManager();
User addCache = new User(); User addCache = new User();
addCache.setOpenid(cacheOpenid); addCache.setOpenid(cacheOpenId);
addCache.setUnionId(authData.getUnionId()); addCache.setUnionId(tokenData.getUnionId());
addCache.setAvatar(authData.getAvatar()); addCache.setAvatar(tokenData.getAvatar());
addCache.setNickName(authData.getNickName()); addCache.setNickName(tokenData.getNickName());
addCache.setPatientList(patients); addCache.setPatientList(patients);
cache.put(cacheOpenid, addCache); cache.put(cacheOpenId, addCache);
} else { } else {
patients = user.getPatientList(); patients = user.getPatientList();
} }
Map<String, Object> map = new HashMap<>(); AuthResultData authResultData = new AuthResultData();
map.put("openid", cacheOpenid); authResultData.setDate(new Date());
map.put("token", token); authResultData.setOpenid(cacheOpenId);
map.put("enOpenId", AesWxHelper.encode(cacheOpenid, true)); authResultData.setToken(token);
map.put("enUnionId", AesWxHelper.encode(authData.getUnionId(), true)); authResultData.setEnOpenId(AesWxHelper.encode(cacheOpenId, true));
map.put("date", new Date()); authResultData.setEnUnionId(AesWxHelper.encode(tokenData.getUnionId(), true));
map.put("avatar", authData.getAvatar()); authResultData.setNickName(tokenData.getNickName());
map.put("nickName", authData.getNickName()); authResultData.setAvatar(tokenData.getAvatar());
map.put("patients", CodeHelper.get28UUID() + Base64Helper.encode(URLEncoder.encode(JsonHelper.toJsonString(patients), "UTF-8"))); authResultData.setPatientList(patients);
map.put("enParams", AesMicroHelper.encode(cacheOpenid)); authResultData.setEnParams(AesMicroHelper.encode(cacheOpenId));
return Result.success(map); authResultData.setEnGmcUUID(AesWxHelper.encode(CodeHelper.get32UUID()));
return authResultData;
} }
HttpSession session = request.getSession(); public static AuthResultData getCacheUserData(HttpServletRequest request, String openId, String state, String isUserInfo, String authSessionId) {
Object sessionOpenId = session.getAttribute("openid"); log.info("[微信认证]openid={}", openId);
String openid = sessionOpenId == null ? null : sessionOpenId.toString(); AuthResultData authResultData = new AuthResultData();
boolean isFindUserInfo = ("true".equals(isUserInfo));
log.info("[微信认证] openid={}, authSessionId={}", openid, authSessionId); if (openId == null) {
if (!ObjectUtils.isEmpty(authSessionId) && ObjectUtils.isEmpty(openid)) { authResultData.setAuthUrl(getAuthUrl(request, state, isFindUserInfo, null, authSessionId));
openid = WxCacheHelper.getOpenIdByAIDCache(authSessionId); return authResultData;
log.warn("[微信AID认证]openid={}", openid);
} }
if (openid != null) { User user = WxCacheHelper.getCacheUser(openId);
log.info("[微信认证]openid={}", openid);
User user = WxCacheHelper.getCacheUser(openid);
if (user == null) { if (user == null) {
return Result.success(getAuthUrl(request, state, isFindUserInfo, UID, authSessionId)); authResultData.setAuthUrl(getAuthUrl(request, state, isFindUserInfo, null, authSessionId));
return authResultData;
} else { } else {
if (ObjectUtils.isEmpty(openid)) { if (ObjectUtils.isEmpty(openId)) {
openid = user.getOpenid(); // sessionId认证openid补充 openId = user.getOpenid(); // sessionId认证openid补充
} }
} }
if (isFindUserInfo) { // 更换授权模式,需更新信息 if (isFindUserInfo) { // 更换授权模式,需更新信息
if (user.getNickName() == null || user.getAvatar() == null) { if (user.getNickName() == null || user.getAvatar() == null) {
return Result.success(getAuthUrl(request, state, true, UID, authSessionId)); authResultData.setAuthUrl(getAuthUrl(request, state, true, null, authSessionId));
return authResultData;
} }
} }
Map<String, Object> map = new HashMap<>(); authResultData.setDate(new Date());
map.put("openid", openid); authResultData.setOpenid(openId);
map.put("token", new AuthData().createToken(WeChatConfig.APP_ID, openid, user.getUnionId(), user.getAvatar(), user.getNickName())); authResultData.setToken(new AuthTokenData().createToken(WeChatConfig.APP_ID, openId, user.getUnionId(), user.getAvatar(), user.getNickName()));
map.put("enOpenId", AesWxHelper.encode(openid, true)); authResultData.setEnOpenId(AesWxHelper.encode(openId, true));
map.put("enUnionId", AesWxHelper.encode(user.getUnionId(), true)); authResultData.setEnUnionId(AesWxHelper.encode(user.getUnionId(), true));
map.put("date", new Date()); authResultData.setNickName(user.getNickName());
map.put("avatar", user.getAvatar()); authResultData.setAvatar(user.getAvatar());
map.put("nickName", user.getNickName()); authResultData.setPatientList(user.getPatientList());
map.put("patients", CodeHelper.get28UUID() + Base64Helper.encode(URLEncoder.encode(JsonHelper.toJsonString(user.getPatientList()), "UTF-8"))); authResultData.setEnParams(AesMicroHelper.encode(openId));
map.put("enParams", AesMicroHelper.encode(openid)); authResultData.setEnGmcUUID(AesWxHelper.encode(CodeHelper.get32UUID()));
return Result.success(map); return authResultData;
} }
return Result.success(getAuthUrl(request, state, isFindUserInfo, UID, authSessionId)); public List<Patient> repeatPatients(String reqDomain, List<Patient> patientList, String gmcOpenId) throws Exception {
// 数据去重
JsonResult jsonResult = postForm(reqDomain + "patient/authGMCPatients", params -> {
params.put("gmcOpenId", AesWxHelper.encode(gmcOpenId, true));
}, headers -> {
headers.add("gmcOpenId", AesWxHelper.encode(gmcOpenId, true));
});
if (jsonResult.success()) {
List<Patient> gmcPatientList = jsonResult.dataMapGetNodeToList(Patient.class);
// authResultData.setPatientList(patientList);
} }
return patientList;
}
private static final String OAUTH_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + WeChatConfig.APP_ID + "&redirect_uri="; private static final String OAUTH_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + WeChatConfig.APP_ID + "&redirect_uri=";
@ -263,10 +375,10 @@ public class WxAuthHelper {
String api = isFindUserInfo ? "u_auth" : "b_auth"; String api = isFindUserInfo ? "u_auth" : "b_auth";
String scope = isFindUserInfo ? "snsapi_userinfo" : "snsapi_base"; String scope = isFindUserInfo ? "snsapi_userinfo" : "snsapi_base";
UID = toURLParam(UNION_ID_NAME, UID); String enUID = toURLParam(GMC_ID, AesWxHelper.encode(UID, true));
String enSID = toURLParam(AUTH_SESSION_ID_NAME, AesWxHelper.encode(SID, true)); String enSID = toURLParam(AUTH_SESSION_ID_NAME, AesWxHelper.encode(SID, true));
String params = enSID + UID; String params = enSID + enUID;
try { try {
params = ObjectUtils.isEmpty(params) ? "" : URLEncoder.encode(params, "UTF-8"); params = ObjectUtils.isEmpty(params) ? "" : URLEncoder.encode(params, "UTF-8");
log.warn("[认证链接参数] params={}", params); log.warn("[认证链接参数] params={}", params);
@ -333,6 +445,10 @@ public class WxAuthHelper {
} }
public static JsonResult postForm(String url, OkHttpHelper.MapParams params, OkHttpHelper.Header header) {
return OkHttpHelper.postForm(url, params, header, JsonResultEnum.SYS_MICRO);
}
// // 医共体开启 & 不是支付授权 // // 医共体开启 & 不是支付授权
// private static boolean isAuthGMC(boolean isPayOAuth) { // private static boolean isAuthGMC(boolean isPayOAuth) {
// return WeChatConfig.IS_ENABLE_GMC && !isPayOAuth; // return WeChatConfig.IS_ENABLE_GMC && !isPayOAuth;

@ -2,7 +2,6 @@ package com.ynxbd.wx.wxfactory;
import com.ynxbd.common.bean.User; import com.ynxbd.common.bean.User;
import com.ynxbd.common.config.EhCacheConfig; import com.ynxbd.common.config.EhCacheConfig;
import com.ynxbd.wx.config.WeChatConfig;
import com.ynxbd.wx.wxfactory.base.auth.models.AccessToken; import com.ynxbd.wx.wxfactory.base.auth.models.AccessToken;
import com.ynxbd.wx.wxfactory.base.auth.models.JsapiTicket; import com.ynxbd.wx.wxfactory.base.auth.models.JsapiTicket;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -20,12 +19,12 @@ public class WxCacheHelper {
private static Cache<String, JsapiTicket> JSAPI_TICKET_CACHE; private static Cache<String, JsapiTicket> JSAPI_TICKET_CACHE;
private static Cache<String, String> AID_CACHE; private static Cache<String, String> AUTH_SESSION_ID_CACHE;
static { static {
createUserCacheManager(); createUserCacheManager();
createAccessTokenCache(); createAccessTokenCache();
createAuthSessionIdManager(); createAuthSessionIdCacheManager();
} }
@ -143,34 +142,34 @@ public class WxCacheHelper {
} }
private synchronized static void createAuthSessionIdManager() { private synchronized static void createAuthSessionIdCacheManager() {
if (AID_CACHE == null) { if (AUTH_SESSION_ID_CACHE == null) {
AID_CACHE = EhCacheConfig.createCacheTTL(String.class, String.class, "auth_session_id_cache", (3600L)); // 一个小时 AUTH_SESSION_ID_CACHE = EhCacheConfig.createCacheTTL(String.class, String.class, "auth_session_id_cache", (3600L)); // 一个小时
} }
} }
public static String getOpenIdByAIDCache(String authSessionId) { public static String findOpenIdBySessionIdCache(String authSessionId) {
if (AID_CACHE == null) { if (AUTH_SESSION_ID_CACHE == null) {
createAuthSessionIdManager(); createAuthSessionIdCacheManager();
} }
if (ObjectUtils.isEmpty(authSessionId)) { if (ObjectUtils.isEmpty(authSessionId)) {
return null; return null;
} }
if (AID_CACHE.containsKey(authSessionId)) { if (AUTH_SESSION_ID_CACHE.containsKey(authSessionId)) {
return AID_CACHE.get(authSessionId); return AUTH_SESSION_ID_CACHE.get(authSessionId);
} }
return null; return null;
} }
public static void putOpenIdToAIDCache(String authSessionId, String openId) { public static void putOpenIdCacheToSessionIdCache(String authSessionId, String openId) {
if (AID_CACHE == null) { if (AUTH_SESSION_ID_CACHE == null) {
createAuthSessionIdManager(); createAuthSessionIdCacheManager();
} }
if (ObjectUtils.isEmpty(authSessionId)) { if (ObjectUtils.isEmpty(authSessionId)) {
return; return;
} }
if (!AID_CACHE.containsKey(authSessionId)) { if (!AUTH_SESSION_ID_CACHE.containsKey(authSessionId)) {
AID_CACHE.put(authSessionId, openId); AUTH_SESSION_ID_CACHE.put(authSessionId, openId);
} }
} }

@ -0,0 +1,65 @@
package com.ynxbd.wx.wxfactory.base.auth.models;
import com.ynxbd.common.bean.Patient;
import com.ynxbd.common.helper.common.Base64Helper;
import com.ynxbd.common.helper.common.CodeHelper;
import com.ynxbd.common.helper.common.JsonHelper;
import com.ynxbd.wx.wxfactory.AesWxHelper;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import java.io.Serializable;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;
@Slf4j
@Getter
@Setter
@ToString
@NoArgsConstructor
public class AuthResultData implements Serializable {
private static final long serialVersionUID = 20251218170700001L;
private Date date;
private String token;
private String openid;
private String enOpenId;
private String enUnionId;
private String avatar;
private String nickName;
private String patients;
private List<Patient> patientList;
private String enParams;
private String authUrl;
private String enGmcUUID;
private String enGmcOpenId;
public boolean hasAuthUrl() {
return !ObjectUtils.isEmpty(authUrl);
}
// 清除无需返回的数据
public AuthResultData toResultData() {
try {
this.patients = CodeHelper.get28UUID() + Base64Helper.encode(URLEncoder.encode(JsonHelper.toJsonString(this.patientList), "UTF-8"));
} catch (Exception e) {
log.error(e.getMessage());
}
this.patientList = null;
this.authUrl = null;
if (ObjectUtils.isEmpty(this.enGmcUUID)) {
this.enGmcUUID = AesWxHelper.encode(CodeHelper.get32UUID());
}
return this;
}
}

@ -18,7 +18,7 @@ import java.io.Serializable;
@ToString @ToString
@NoArgsConstructor @NoArgsConstructor
@Slf4j @Slf4j
public class AuthData implements Serializable { public class AuthTokenData implements Serializable {
private static final long serialVersionUID = 202511101525001L; private static final long serialVersionUID = 202511101525001L;
private String appId; private String appId;
@ -53,29 +53,29 @@ public class AuthData implements Serializable {
if (ObjectUtils.isEmpty(dataJson)) { if (ObjectUtils.isEmpty(dataJson)) {
return null; return null;
} }
AuthData authData = JsonHelper.parseObject(dataJson, AuthData.class); AuthTokenData authTokenData = JsonHelper.parseObject(dataJson, AuthTokenData.class);
if (authData == null) { if (authTokenData == null) {
return null; return null;
} }
String cacheOpenid = authData.getOpenId(); String cacheOpenid = authTokenData.getOpenId();
if (ObjectUtils.isEmpty(cacheOpenid)) { if (ObjectUtils.isEmpty(cacheOpenid)) {
return null; return null;
} }
String cacheAppId = authData.getAppId(); String cacheAppId = authTokenData.getAppId();
if (!cacheAppId.equals(serverAppId)) { if (!cacheAppId.equals(serverAppId)) {
log.warn("[微信认证]token中的AppId和配置的不一致"); log.warn("[微信认证]token中的AppId和配置的不一致");
return null; return null;
} }
String cacheTime = authData.getCreateTime(); String cacheTime = authTokenData.getCreateTime();
Boolean hasValidity = DateHelper.inDateRangeByDay(-3, cacheTime); Boolean hasValidity = DateHelper.inDateRangeByDay(-3, cacheTime);
if (hasValidity != null && hasValidity) { // 在有效期内 if (hasValidity != null && hasValidity) { // 在有效期内
this.openId = cacheOpenid; this.openId = cacheOpenid;
this.unionId = authData.getUnionId(); this.unionId = authTokenData.getUnionId();
this.appId = authData.getAppId(); this.appId = authTokenData.getAppId();
this.avatar = authData.getAvatar(); this.avatar = authTokenData.getAvatar();
this.nickName = authData.getNickName(); this.nickName = authTokenData.getNickName();
this.createTime = cacheTime; this.createTime = cacheTime;
return cacheOpenid; return cacheOpenid;
} }
Loading…
Cancel
Save