微信后端代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

202 lines
8.9 KiB

package com.ynxbd.wx.wxfactory;
import com.ynxbd.common.bean.User;
import com.ynxbd.common.helper.common.AesMicroHelper;
import com.ynxbd.common.helper.common.Base64Helper;
import com.ynxbd.common.helper.common.CodeHelper;
import com.ynxbd.common.helper.common.JsonHelper;
import com.ynxbd.common.result.Result;
import com.ynxbd.common.service.PatientService;
import com.ynxbd.wx.config.WeChatConfig;
import com.ynxbd.wx.wxfactory.bean.SnsOath2AccessToken;
import com.ynxbd.wx.wxfactory.bean.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.Map;
@Slf4j
public class WxAuthHelper {
private static final int SESSION_MAX_INACTIVE_INTERVAL = 60 * 60; // session最大存活时间 1H
public static String auth(HttpServletRequest request, HttpServletResponse response, boolean isUserInfo) {
String code = request.getParameter("code");
String state = request.getParameter("state");
String hash = request.getParameter("hash");
try {
if (hash == null) {
hash = "";
} else {
hash = Base64Helper.decode(hash);
hash = URLDecoder.decode(hash, "UTF-8");
}
SnsOath2AccessToken snsToken = WxFactory.Base.OAuth().oauth2AccessToken(WeChatConfig.APP_ID, WeChatConfig.APP_SECRET, code);
if (snsToken != null) {
String openid = snsToken.getOpenid();
if (openid != null) {
HttpSession session = request.getSession();
session.setMaxInactiveInterval(SESSION_MAX_INACTIVE_INTERVAL);
session.setAttribute("openid", openid);
Cache<String, User> cache = WxCacheHelper.getUserCache();
if (WeChatConfig.isDevUser(openid) || !cache.containsKey(openid)) {
String unionId = snsToken.getUnionid();
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());
Integer sex = snsUser.getSex();
if (sex != null) {
user.setGender(sex == 1 ? "男" : "女");
}
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());
Integer sex = snsUser.getSex();
if (sex != null) {
user.setGender(sex == 1 ? "男" : "女");
}
}
}
}
}
}
}
if (hash == null) hash = "";
if (state == null) state = "";
String protocol = ""; //
int index = state.indexOf("@protocol=");
if (index == -1) index = state.indexOf("%40protocol="); // 防止数据转义失败
if (index != -1) {
protocol = state.substring(index);
state = state.substring(0, index);
}
String domain = WeChatConfig.getBaseDomain(WeChatConfig.HAS_HTTPS_BY_BASE_URL || "@protocol=1".equals(protocol)); // 配置中baseURL有"https"时优先级最高 ["@protocol=1"为https;"@protocol=0"为默认的http;]
if (state.contains(".html")) {
return domain + state + hash;
} else {
String baseUrl = WeChatConfig.getBaseUrl();
if (baseUrl != null && state.contains(baseUrl)) {
return domain + state + hash;
}
}
} catch (Exception e) {
log.error("[微信][获取重定向链接异常]{}", e.getMessage());
}
return null;
}
public static Result isAuth(HttpServletRequest request) throws Exception {
HttpSession session = request.getSession();
Object openid = session.getAttribute("openid");
if (openid != null) {
User user = WxCacheHelper.getCacheUser((String) openid);
if (user == null) {
return Result.success(getAuthUrl(request));
}
String isUserInfo = request.getParameter("isUserInfo");
if ("true".equals(isUserInfo)) { // 更换授权模式,需更新信息
if (user.getNickName() == null || user.getAvatar() == null) {
return Result.success(getAuthUrl(request));
}
}
Map<String, Object> map = new HashMap<>();
map.put("openid", openid);
map.put("unionId", user.getUnionId());
map.put("date", new Date());
map.put("avatar", user.getAvatar());
map.put("nickName", user.getNickName());
map.put("patients", CodeHelper.get28UUID() + Base64Helper.encode(URLEncoder.encode(JsonHelper.toJsonString(user.getPatientList()), "UTF-8")));
map.put("hash", request.getParameter("hash"));
map.put("enParams", AesMicroHelper.encode(openid.toString()));
return Result.success(map);
}
return Result.success(getAuthUrl(request));
}
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) {
// StringBuffer url = request.getRequestURL();
// String baseUrl = url.delete(url.length() - request.getRequestURI().length(), url.length()).append(request.getServletContext().getContextPath()).append("/").toString();
String state = request.getParameter("state");
String hash = request.getParameter("hash");
String isUserInfo = request.getParameter("isUserInfo");
String protocolState = request.getParameter("protocolState"); // 1:https;0:http
if (ObjectUtils.isEmpty(protocolState)) {
protocolState = "0";
}
if (hash == null) {
hash = "";
}
if (state != null) {
String decode = Base64Helper.decode(state);
if (!decode.contains(".html") && !decode.contains(".jsp")) {
decode = "my-info.html";
}
String api = ("true".equals(isUserInfo) ? "u_auth" : "b_auth");
String scope = ("true".equals(isUserInfo) ? "snsapi_userinfo" : "snsapi_base");
// 配置中baseURL有"https"时优先级最高
state = OAUTH_URL + WeChatConfig.getBaseUrlByState((WeChatConfig.HAS_HTTPS_BY_BASE_URL || "1".equals(protocolState))) +
"wx_auth/" + api +
"?hash=" + hash +
"&response_type=code" +
"&scope=" + scope + "&forcePopup=true" +
"&state=" + decode +
"%40protocol=" + protocolState +
"#wechat_redirect";
state = Base64Helper.encode(state);
}
return state;
}
}