烦人的bug,对接微信第三方登陆获取用户信息
我最洋气
烦了一天了,百度都给我烦烂了还是没有找到好的解决方法,总所周知微信网页授权获取到的 code 只能使用一次(5分钟内有效),使用一次后,马上失效。code会换取openid,此时刷新页面,并不会再次进行授权,而是直接刷新了一下上一次授权跳转后的链接,带的还是上一次的 code (如果你复制当前页面的链接,会发现它就是请求授权的链接,然而,刷新的时候,它访问的并不是这个请求授权链接)。当我们程序报错的时候,微信都会以为这是他们自己的错误,重新返回一个code,这个时候,会出现这个问题,但也不是绝对。
比如我这个问题,一次都还没有请求成功,何来的缓存这么一说,更怎么会返回2个code呢?主要还是自己代码的问题,废话不多说,上代码
private Map<String,String> wxLogin(HttpServletRequest request, String code, String state, HttpServletResponse response,
String urls) {
// 打印已经出现的code
logs.info("用户已登陆,返回code==" + code + " 获取" + request);
// 获取access_token等信息
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + SpeedyLoginConfig.WX_AppID
+ "&secret=" + SpeedyLoginConfig.WX_AppSecret + "&code=" + code + "&grant_type=authorization_code";
String accessToken = sendGet(url);
logs.info("登陆成功,获取access_token中。。" + accessToken);
// 将获取到的数据转化为map便于遍历查询
Object parse = JSONUtils.parse(accessToken);
Map<String, String> map = (Map<String, String>) parse;
logs.info(map);
// 判断是否获取到access_token
if (map.get("access_token") != null) {
// 已经获取到access_token,可以用此来获取user
WXaccess_token = map.get("access_token");
WXrefresh_token = map.get("refresh_token");
WXopenid = map.get("openid");
Map<String,Object> maps = userinfoURL(WXaccess_token, WXopenid);// 向微信端获取用户信息
// 将数据返回给首页
String nickname = (String) maps.get("nickname");
String unionid = (String) maps.get("unionid");
String icon = (String) maps.get("headimgurl");
logs.info(icon);
map = new HashMap<>();
map.put("username", nickname);
map.put("unionid", unionid);
map.put("url", icon);
return map;
} else {
// 用户code已过期,重定向回index页面
logs.info(map.get("errmsg"));
logs.info(accessToken.substring(1, accessToken.length() - 2) + "");
String postIndex = postIndex(0, "", "", 1, response, urls, "WX", request);
try {
response.sendRedirect(postIndex);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
相信大家已经看出问题所在了,我的请求直接在微信的回调里面,获取用户OPENID后,就去执行了获取用户信息进行返回,当然报错咯
public Map<String, String> setUser(Param param) {
String code = param.getName();
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + WXpayConfig.jsappid + "&secret="
+ WXpayConfig.secret + "&code=" + code + "&grant_type=authorization_code";
String sendGet = sendGet(url);
Object parse = JSONUtils.parse(sendGet);
@SuppressWarnings("unchecked")
Map<String, String> map = (Map<String, String>) parse;
String openid = map.get("openid");
String accessToken = map.get("access_token");
String api = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openid
+ "&lang=zh_CN";
sendGet = sendGet(api);
// 将获取到的数据转化为map便于遍历查询
parse = JSONUtils.parse(sendGet);
@SuppressWarnings("unchecked")
Map<String, String> maps = (Map<String, String>) parse;
String nickname = maps.get("nickname");
String unionid = maps.get("unionid");
String icon = maps.get("headimgurl");
System.out.println(icon);
map = new HashMap<>();
map.put("username", nickname);
map.put("unionid", unionid);
map.put("url", icon);
return map;
}
与其说别人的错,还不如多看看自己写的代码,没茅台~