公众号网页授code多次回调?
场景:公众号(已认证)自定义页面中是接口地址,在接口中获取code(成功),并通过 code 获取accessoken(成功),再获取用户信息(成功),最后通过重定向到最终页面 responses.sendRedirect(“url” + “?userId=” + userId);(失效)
重定向前后都输出日志了,说明重定向走到了,但是没有生效,这是什么原因呢?
是因为获取 code 的时候微信回调了四次吗?还是什么原因?
还有为什么微信会回调四次呢?
2 回复
[@GetMapping](/user/GetMapping)(value = "/spots")
public void spotsDescAuth(HttpServletRequest request, HttpServletResponse responses) {
synchronized (this) {
try {
//从 redis 获取 code 对应的 accesstoken 信息,避免微信多次回调
Map<String, String> userIdMap = codeAndUserIdRedis.get(codeAndUser);
String code =
getWxCode(request, responses);
if (code != null) {
String userId;
if (!CollectionUtils.isEmpty(userIdMap) && userIdMap.containsKey(code)) {
userId = userIdMap.get(request.getParameter("code"));
logger.info("redis 获取的 userid-》" + userId);
} else {
userId = wxChatAuth(request, responses, code, SPOTS);
HashMap<String, String> stringStringHashMap = new HashMap<>();
stringStringHashMap.put(code,userId);
codeAndUserIdRedis.setEx(codeAndUser,stringStringHashMap,7200);
logger.info("重新获取的 userid-》" + userId);
}
responses.setHeader("REDIRECT","REDIRECT");//告诉ajax要重定向
responses.setHeader("PATH","SPOTS"+ "?userId=" + userId);//ip为服务器ip地址,在此用ip代指
responses.sendRedirect(SPOTS + "?userId=" + userId);
logger.info("导游导览 url" + SPOTS + "?userId=" + userId);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
private String getWxCode(HttpServletRequest request, HttpServletResponse response) {
String redirect = null;
String code = request.getParameter("code");
logger.info("code:---->" + code);
if (StringUtils.isBlank(code)) {
try {
redirect = URLEncoder.encode(request.getRequestURL().toString(), "utf-8");
logger.info("回调地址:-》" + redirect);
StringBuffer str = new StringBuffer();
str.append(authorizeUrl + "&redirect_uri=" + redirect);
str.append("&response_type=code&scope=snsapi_userinfo&state=123#connect_redirect=1#wechat_redirect");
response.sendRedirect(str.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
return code;
}
private String wxChatAuth(HttpServletRequest request, HttpServletResponse response, String code, String url) {
Map<String, User> list = redisToken.get(webAccessToken);
logger.info(webAccessToken + ":->" + list);
User user = new User();
String result;
//从 redis 获取 code 对应的 accesstoken 信息,避免微信多次回调
Map<String, String> codeMap = this.codeAndAccessTokenRedis.get(codeAndAccessToken);
if (!CollectionUtils.isEmpty(codeMap) && codeMap.containsKey(code)) {
result = codeMap.get(code);
logger.info("redis 中的 result:->" + result);
} else {
//获取网页授权 access_token,并组装 user
String uri = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + AppID + "&secret=" + AppSecret + "&code=" + code + "&grant_type=authorization_code";
logger.info("网页授权 uri:->" + uri);
result = com.ly.goddess.tools.HttpClientUtil.doGet(uri, "utf-8");
logger.info("微信获取的result:->" + result);
Map<String, String> newCodeMap = new HashMap<>();
newCodeMap.put(code, result);
codeAndAccessTokenRedis.setEx(codeAndAccessToken, newCodeMap, 7200);
}
StringBuffer userInfoUrl = new StringBuffer();
String getUserInfo = "https://api.weixin.qq.com/sns/userinfo?access_token=";
if (result != null) {
JSONObject object = JSON.parseObject(result);
if (object != null && object.getString("openid") != null && object.getString("access_token") != null) {
logger.info("第一次获取的 openid :-》" + object.getString("openid"));
user.setOpen_id(object.getString("openid"));
String accessToken = object.getString("access_token");
Integer expiresIn = object.getInteger("expires_in");
if (!StringUtils.isBlank(accessToken)) {
//获取 redis 中存储的 accesstoken,避免多次获取
if (!CollectionUtils.isEmpty(list) && list.containsKey(accessToken)) {
String openId = user.getOpen_id();
BeanUtil.copyPropertiesIgnoreNull(list.get(accessToken), user);
user.setOpen_id(openId);
} else {
userInfoUrl.append(getUserInfo).append(accessToken).append("&openid=").append(object.getString("openid")).append("&lang=zh_CN");
logger.info("获取用户信息地址:->" + userInfoUrl);
String userInfo = com.ly.goddess.tools.HttpClientUtil.doGet(userInfoUrl.toString(), "utf-8");
logger.info("用户全部信息:-<" + userInfo);
//。。。
HashMap<String, User> userHashMap = new HashMap<>();
userHashMap.put(accessToken, user);
redisToken.setEx(webAccessToken, userHashMap, expiresIn);
}
}
}
}
logger.info("userId:->" + userId);
}
}