|
|
|
|
package com.ynxbd.wx.wxfactory;
|
|
|
|
|
|
|
|
|
|
import com.ynxbd.common.bean.GMCUser;
|
|
|
|
|
import com.ynxbd.common.bean.Patient;
|
|
|
|
|
import com.ynxbd.common.bean.User;
|
|
|
|
|
import com.ynxbd.common.helper.common.*;
|
|
|
|
|
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.service.GMCUserService;
|
|
|
|
|
import com.ynxbd.common.service.PatientService;
|
|
|
|
|
import com.ynxbd.wx.config.WeChatConfig;
|
|
|
|
|
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.SnsUserInfo;
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
import org.apache.commons.lang3.ObjectUtils;
|
|
|
|
|
import org.ehcache.Cache;
|
|
|
|
|
|
|
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
|
|
import javax.servlet.http.HttpSession;
|
|
|
|
|
import java.net.URLDecoder;
|
|
|
|
|
import java.net.URLEncoder;
|
|
|
|
|
import java.util.Date;
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
|
|
@Slf4j
|
|
|
|
|
public class WxAuthHelper {
|
|
|
|
|
private static final int SESSION_MAX_INACTIVE_INTERVAL = 60 * 60; // session最大存活时间 1H
|
|
|
|
|
|
|
|
|
|
private static final String P_PREFIX = "_@"; // 前缀
|
|
|
|
|
private static final String P_SUFFIX = ":"; // 后缀
|
|
|
|
|
|
|
|
|
|
private static final String AUTH_SESSION_ID_NAME = "SID";
|
|
|
|
|
private static final String GMC_ID = "GMCId";
|
|
|
|
|
private static final String OPENID = "openid";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static String auth(HttpServletRequest request, HttpServletResponse response, boolean isUserInfo) {
|
|
|
|
|
try {
|
|
|
|
|
String code = request.getParameter("code");
|
|
|
|
|
String state = request.getParameter("state"); // base64
|
|
|
|
|
Map<String, String> paramsMap = getParamsMap(request.getParameter("p"));
|
|
|
|
|
|
|
|
|
|
log.info("[认证授权] code={}, state={}, paramsMap={}", code, state, JsonHelper.toJsonString(paramsMap));
|
|
|
|
|
|
|
|
|
|
state = state == null ? "" : URLDecoder.decode(Base64Helper.decode(state), "UTF-8");
|
|
|
|
|
String authSessionId = AesWxHelper.decode(paramsMap.get(AUTH_SESSION_ID_NAME));
|
|
|
|
|
|
|
|
|
|
log.info("[认证授权-解码] authSessionId={}, state={}", authSessionId, state);
|
|
|
|
|
|
|
|
|
|
SnsOath2AccessToken snsToken = WxFactory.Base.OAuth().oauth2AccessToken(WeChatConfig.APP_ID, WeChatConfig.APP_SECRET, code);
|
|
|
|
|
log.info("[认证授权]信息 snsToken={}", JsonHelper.toJsonString(snsToken));
|
|
|
|
|
if (snsToken != null) {
|
|
|
|
|
String openid = snsToken.getOpenid();
|
|
|
|
|
String unionId = snsToken.getUnionid();
|
|
|
|
|
|
|
|
|
|
if (openid != null) {
|
|
|
|
|
HttpSession session = request.getSession();
|
|
|
|
|
session.setMaxInactiveInterval(SESSION_MAX_INACTIVE_INTERVAL);
|
|
|
|
|
session.setAttribute(OPENID, openid);
|
|
|
|
|
|
|
|
|
|
WxCacheHelper.putOpenIdCacheToSessionIdCache(authSessionId, openid);
|
|
|
|
|
|
|
|
|
|
Cache<String, User> cache = WxCacheHelper.getUserCacheManager();
|
|
|
|
|
if (WeChatConfig.isDevUser(openid) || !cache.containsKey(openid)) {
|
|
|
|
|
User user = new User();
|
|
|
|
|
user.setUnionId(unionId);
|
|
|
|
|
user.setOpenid(openid);
|
|
|
|
|
user.setIsSnapShotUser(snsToken.getIsSnapShotUser());
|
|
|
|
|
user.setPatientList(new PatientService().queryPatientList(openid, unionId, true));
|
|
|
|
|
|
|
|
|
|
if (isUserInfo) {
|
|
|
|
|
SnsUserInfo snsUser = WxFactory.Base.OAuth().snsUserInfo(snsToken.getAccessToken(), openid, "zh_CN", 3);
|
|
|
|
|
if (snsUser != null) {
|
|
|
|
|
user.setCountry(snsUser.getCountry());
|
|
|
|
|
user.setAvatar(snsUser.getHeadImgUrl());
|
|
|
|
|
user.setNickName(snsUser.getNickname_emoji());
|
|
|
|
|
user.setProvince(snsUser.getProvince());
|
|
|
|
|
user.setGenderByInt(snsUser.getSex());
|
|
|
|
|
user.setCity(snsUser.getCity());
|
|
|
|
|
user.setLanguage(snsUser.getLanguage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
cache.put(openid, user);
|
|
|
|
|
} else {
|
|
|
|
|
if (isUserInfo) {
|
|
|
|
|
User user = cache.get(openid);
|
|
|
|
|
if (user != null && user.getAvatar() == null && user.getNickName() == null) {
|
|
|
|
|
SnsUserInfo snsUser = WxFactory.Base.OAuth().snsUserInfo(snsToken.getAccessToken(), openid, "zh_CN", 3);
|
|
|
|
|
if (snsUser != null) {
|
|
|
|
|
user.setAvatar(snsUser.getHeadImgUrl());
|
|
|
|
|
user.setNickName(snsUser.getNickname_emoji());
|
|
|
|
|
user.setGenderByInt(snsUser.getSex());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (WeChatConfig.HAS_HTTPS_BY_BASE_URL) { // 强制为https
|
|
|
|
|
String httpsURL = URLHelper.URLToHttps(state);
|
|
|
|
|
state = httpsURL == null ? "" : httpsURL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (state.contains(".html")) { // 网页授权配置
|
|
|
|
|
return state;
|
|
|
|
|
} else {
|
|
|
|
|
String baseUrl = WeChatConfig.getBaseURL();
|
|
|
|
|
if (baseUrl != null && state.contains(baseUrl)) {
|
|
|
|
|
return state;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
ErrorHelper.println(e);
|
|
|
|
|
log.error("[微信][获取重定向链接异常]{}", e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static Result isAuth(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
|
|
|
|
String token = request.getParameter("token"); // 前端缓存
|
|
|
|
|
String state = request.getParameter("state");
|
|
|
|
|
String isUserInfo = request.getParameter("isUserInfo");
|
|
|
|
|
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;
|
|
|
|
|
if (WeChatConfig.IS_ENABLE_GMC) { // 开启医共体开关 & 是医共体主服务器 & 不是支付授权
|
|
|
|
|
try {
|
|
|
|
|
if (WeChatConfig.IS_GMC_SERVER) {
|
|
|
|
|
authSessionId = AesWxHelper.decode(request.getHeader(AUTH_SESSION_ID_NAME));
|
|
|
|
|
|
|
|
|
|
} else { // 请求转发
|
|
|
|
|
String serverDomain = WeChatConfig.getDomain(false, false);
|
|
|
|
|
if (deState != null && serverDomain != null && !deState.contains(serverDomain)) {
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cacheTokenOpenId != null) {
|
|
|
|
|
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());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 主体服务器认证
|
|
|
|
|
*/
|
|
|
|
|
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("state", state);
|
|
|
|
|
params.put("isUserInfo", "false");
|
|
|
|
|
}, headers -> {
|
|
|
|
|
if (!ObjectUtils.isEmpty(sessionId)) {
|
|
|
|
|
headers.add(AUTH_SESSION_ID_NAME, AesWxHelper.encode(WeChatConfig.APP_ID + ":" + sessionId));
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
Result result = Result.dataToResult(resultJson, true);
|
|
|
|
|
if (!result.isOK()) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
String dataStr = result.toDataStr();
|
|
|
|
|
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);
|
|
|
|
|
User user = WxCacheHelper.getCacheUser(cacheOpenId);
|
|
|
|
|
List<Patient> patients;
|
|
|
|
|
if (user == null) {
|
|
|
|
|
patients = new PatientService().queryPatientList(cacheOpenId, null, true);
|
|
|
|
|
Cache<String, User> cache = WxCacheHelper.getUserCacheManager();
|
|
|
|
|
User addCache = new User();
|
|
|
|
|
addCache.setOpenid(cacheOpenId);
|
|
|
|
|
addCache.setUnionId(tokenData.getUnionId());
|
|
|
|
|
addCache.setAvatar(tokenData.getAvatar());
|
|
|
|
|
addCache.setNickName(tokenData.getNickName());
|
|
|
|
|
addCache.setPatientList(patients);
|
|
|
|
|
cache.put(cacheOpenId, addCache);
|
|
|
|
|
} else {
|
|
|
|
|
patients = user.getPatientList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AuthResultData authResultData = new AuthResultData();
|
|
|
|
|
authResultData.setDate(new Date());
|
|
|
|
|
authResultData.setOpenid(cacheOpenId);
|
|
|
|
|
authResultData.setToken(token);
|
|
|
|
|
authResultData.setEnOpenId(AesWxHelper.encode(cacheOpenId, true));
|
|
|
|
|
authResultData.setEnUnionId(AesWxHelper.encode(tokenData.getUnionId(), true));
|
|
|
|
|
authResultData.setNickName(tokenData.getNickName());
|
|
|
|
|
authResultData.setAvatar(tokenData.getAvatar());
|
|
|
|
|
authResultData.setPatientList(patients);
|
|
|
|
|
authResultData.setEnParams(AesMicroHelper.encode(cacheOpenId));
|
|
|
|
|
authResultData.setEnGmcUUID(AesWxHelper.encode(CodeHelper.get32UUID()));
|
|
|
|
|
return authResultData;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static AuthResultData getCacheUserData(HttpServletRequest request, String openId, String state, String isUserInfo, String authSessionId) {
|
|
|
|
|
log.info("[微信认证]openid={}", openId);
|
|
|
|
|
AuthResultData authResultData = new AuthResultData();
|
|
|
|
|
boolean isFindUserInfo = ("true".equals(isUserInfo));
|
|
|
|
|
if (openId == null) {
|
|
|
|
|
authResultData.setAuthUrl(getAuthUrl(request, state, isFindUserInfo, null, authSessionId));
|
|
|
|
|
return authResultData;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
User user = WxCacheHelper.getCacheUser(openId);
|
|
|
|
|
if (user == null) {
|
|
|
|
|
authResultData.setAuthUrl(getAuthUrl(request, state, isFindUserInfo, null, authSessionId));
|
|
|
|
|
return authResultData;
|
|
|
|
|
} else {
|
|
|
|
|
if (ObjectUtils.isEmpty(openId)) {
|
|
|
|
|
openId = user.getOpenid(); // sessionId认证openid补充
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isFindUserInfo) { // 更换授权模式,需更新信息
|
|
|
|
|
if (user.getNickName() == null || user.getAvatar() == null) {
|
|
|
|
|
authResultData.setAuthUrl(getAuthUrl(request, state, true, null, authSessionId));
|
|
|
|
|
return authResultData;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
authResultData.setDate(new Date());
|
|
|
|
|
authResultData.setOpenid(openId);
|
|
|
|
|
authResultData.setToken(new AuthTokenData().createToken(WeChatConfig.APP_ID, openId, user.getUnionId(), user.getAvatar(), user.getNickName()));
|
|
|
|
|
authResultData.setEnOpenId(AesWxHelper.encode(openId, true));
|
|
|
|
|
authResultData.setEnUnionId(AesWxHelper.encode(user.getUnionId(), true));
|
|
|
|
|
authResultData.setNickName(user.getNickName());
|
|
|
|
|
authResultData.setAvatar(user.getAvatar());
|
|
|
|
|
authResultData.setPatientList(user.getPatientList());
|
|
|
|
|
authResultData.setEnParams(AesMicroHelper.encode(openId));
|
|
|
|
|
authResultData.setEnGmcUUID(AesWxHelper.encode(CodeHelper.get32UUID()));
|
|
|
|
|
return authResultData;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 String getAuthUrl(HttpServletRequest request, String state, boolean isFindUserInfo, String UID, String SID) {
|
|
|
|
|
// StringBuffer url = request.getRequestURL();
|
|
|
|
|
// String baseUrl = url.delete(url.length() - request.getRequestURI().length(), url.length()).append(request.getServletContext().getContextPath()).append("/").toString();
|
|
|
|
|
if (state == null) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String api = isFindUserInfo ? "u_auth" : "b_auth";
|
|
|
|
|
String scope = isFindUserInfo ? "snsapi_userinfo" : "snsapi_base";
|
|
|
|
|
|
|
|
|
|
String enUID = toURLParam(GMC_ID, AesWxHelper.encode(UID, true));
|
|
|
|
|
String enSID = toURLParam(AUTH_SESSION_ID_NAME, AesWxHelper.encode(SID, true));
|
|
|
|
|
|
|
|
|
|
String params = enSID + enUID;
|
|
|
|
|
try {
|
|
|
|
|
params = ObjectUtils.isEmpty(params) ? "" : URLEncoder.encode(params, "UTF-8");
|
|
|
|
|
log.warn("[认证链接参数] params={}", params);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error(e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
state = OAUTH_URL + WeChatConfig.getBaseURL(WeChatConfig.HAS_HTTPS_BY_BASE_URL || isHttpsWithProxy(request)) +
|
|
|
|
|
"wx_auth/" + api +
|
|
|
|
|
"?p=" + params +
|
|
|
|
|
"&response_type=code" +
|
|
|
|
|
"&scope=" + scope +
|
|
|
|
|
"&forcePopup=true" +
|
|
|
|
|
"&state=" + state + // state位置固定
|
|
|
|
|
"#wechat_redirect";
|
|
|
|
|
log.warn("[认证授权链接]state={}", state);
|
|
|
|
|
return Base64Helper.encode(state);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 是否为https请求
|
|
|
|
|
public static boolean isHttpsWithProxy(HttpServletRequest request) {
|
|
|
|
|
// 优先检查代理头(适用于反向代理场景)
|
|
|
|
|
String forwardedProto = request.getHeader("X-Forwarded-Proto");
|
|
|
|
|
if (forwardedProto != null) {
|
|
|
|
|
return "https".equalsIgnoreCase(forwardedProto);
|
|
|
|
|
}
|
|
|
|
|
// 未经过代理,直接检查原生请求
|
|
|
|
|
return request.isSecure();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static String toURLParam(String key, String val) {
|
|
|
|
|
if (ObjectUtils.isEmpty(val)) return "";
|
|
|
|
|
return P_PREFIX + key + P_SUFFIX + val;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Map<String, String> getParamsMap(String params) {
|
|
|
|
|
Map<String, String> paramsMap = new HashMap<>();
|
|
|
|
|
try {
|
|
|
|
|
if (ObjectUtils.isEmpty(params)) {
|
|
|
|
|
return paramsMap;
|
|
|
|
|
}
|
|
|
|
|
params = URLDecoder.decode(params, "UTF-8");
|
|
|
|
|
String[] paramsArr = params.split(P_PREFIX);
|
|
|
|
|
String key, val;
|
|
|
|
|
String[] keyValueArr;
|
|
|
|
|
for (String paramItem : paramsArr) {
|
|
|
|
|
if (paramItem.isEmpty()) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
keyValueArr = paramItem.split(P_SUFFIX, 2); // 分割成最多两部分
|
|
|
|
|
if (keyValueArr.length == 2) {
|
|
|
|
|
key = keyValueArr[0];
|
|
|
|
|
val = keyValueArr[1];
|
|
|
|
|
val = ParamHelper.filterParamNull(val, null);
|
|
|
|
|
if (val != null) {
|
|
|
|
|
paramsMap.put(key, val);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error(e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
return paramsMap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
// return WeChatConfig.IS_ENABLE_GMC && !isPayOAuth;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// private static String getOAuthURL(HttpServletRequest request, boolean isPayOAuth) {
|
|
|
|
|
// boolean isHttps = WeChatConfig.HAS_HTTPS_BY_BASE_URL || isHttpsWithProxy(request);
|
|
|
|
|
// return isAuthGMC(isPayOAuth)
|
|
|
|
|
// ? "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + WeChatConfig.GMC_AUTH_APP_ID + "&redirect_uri=" + WeChatConfig.getGMCAuthDomain(isHttps, true)
|
|
|
|
|
// : "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + WeChatConfig.APP_ID + "&redirect_uri=" + WeChatConfig.getBaseURL(isHttps);
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// private static SnsOath2AccessToken getOath2AccessToken(String code, boolean isPayOAuth) {
|
|
|
|
|
// if (isAuthGMC(isPayOAuth)) {
|
|
|
|
|
// return WxFactory.Base.OAuth().oauth2AccessToken(WeChatConfig.GMC_AUTH_APP_ID, WeChatConfig.GMC_AUTH_APP_SECRET, code);
|
|
|
|
|
// }
|
|
|
|
|
// return WxFactory.Base.OAuth().oauth2AccessToken(WeChatConfig.APP_ID, WeChatConfig.APP_SECRET, code);
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// // 获取重定向链接
|
|
|
|
|
// private static String getAuthDomain(HttpServletRequest request, boolean isPayOAuth) {
|
|
|
|
|
// if (isAuthGMC(isPayOAuth)) {
|
|
|
|
|
// return WeChatConfig.getGMCAuthDomain(true, false); // 强制为https
|
|
|
|
|
// }
|
|
|
|
|
// return WeChatConfig.getDomain(WeChatConfig.HAS_HTTPS_BY_BASE_URL || isHttpsWithProxy(request)); // 配置中baseURL有"https"时优先级最高 ["@protocol=1"为https;"@protocol=0"为默认的http;]
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
}
|