Java微信公众获取用户信息踩的坑记录一下
1、测试号
地址:https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index

记得修改为自己的域名:例子 example.test.com

接下来就是干货,上Java代码
@RequestMapping(value = "/wxLogin", method = RequestMethod.GET)
public String wxLogin() throws ParseException {
// 这个url的域名必须要进行再公众号中进行注册验证,这个地址是成功后的回调地址
String backUrl = "http://xxx.xxx.xxx/wx/callBack";
// 第一步:用户同意授权,获取code
String getCodeUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + WXAuthUtil.APPID
+ "&redirect_uri=" + URLEncoder.encode(backUrl)
+ "&response_type=code"
+ "&scope=snsapi_userinfo"
+ "&state=STATE#wechat_redirect";
logger.info("获取code, getCodeUrl=" + getCodeUrl);
// response.sendRedirect(url);
return "redirect:" + getCodeUrl;// 必须重定向,否则不能成功
} @GetMapping(value = "/callBack")
public String callBack(Model model) throws ServletException, IOException {
String code = request.getParameter("code");
// 第二步:通过code换取网页授权access_token
String getTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + WXAuthUtil.APPID + "&secret="
+ WXAuthUtil.APPSECRET + "&code=" + code + "&grant_type=authorization_code";
logger.info("获取token,getTokenUrl=" + getTokenUrl);
JSONObject getTokenJson = WXAuthUtil.doGetJson(getTokenUrl);
/*
* { "access_token":"ACCESS_TOKEN", "expires_in":7200,
* "refresh_token":"REFRESH_TOKEN", "openid":"OPENID", "scope":"SCOPE" }
*/
logger.info("获取token,getTokenJson=" + getTokenJson.toJSONString());
String openid = getTokenJson.getString("openid");
String access_token = getTokenJson.getString("access_token");
String refresh_token = getTokenJson.getString("refresh_token");
// 第五步验证access_token是否失效;展示都不需要
String vlidTokenUrl = "https://api.weixin.qq.com/sns/auth?access_token=" + access_token + "&openid=" + openid;
logger.info("验证token,vlidTokenUrl=" + vlidTokenUrl);
JSONObject validTokenJson = WXAuthUtil.doGetJson(vlidTokenUrl);
logger.info("验证token,validTokenJson=" + validTokenJson.toJSONString());
if (!"0".equals(validTokenJson.getString("errcode"))) {
// 第三步:刷新access_token(如果需要)-----暂时没有使用,参考文档https://mp.weixin.qq.com/wiki,
String refreshTokenUrl = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=" + openid
+ "&grant_type=refresh_token&refresh_token=" + refresh_token;
logger.info("刷新token,refreshTokenUrl=" + refreshTokenUrl);
JSONObject refreshTokenJson = WXAuthUtil.doGetJson(refreshTokenUrl);
/*
* { "access_token":"ACCESS_TOKEN", "expires_in":7200,
* "refresh_token":"REFRESH_TOKEN", "openid":"OPENID", "scope":"SCOPE" }
*/
logger.info("刷新token,refreshTokenJson=" + refreshTokenJson.toJSONString());
access_token = refreshTokenJson.getString("access_token");
}
// 第四步:拉取用户信息(需scope为 snsapi_userinfo)
String getUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token + "&openid=" + openid
+ "&lang=zh_CN";
logger.info("获取用户信息,getUserInfoUrl=" + getUserInfoUrl.toString());
JSONObject getUserInfoJson = WXAuthUtil.doGetJson(getUserInfoUrl);
/*
* { "openid":" OPENID", " nickname": NICKNAME, "sex":"1", "province":"PROVINCE"
* "city":"CITY", "country":"COUNTRY", "headimgurl":
* "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
* "privilege":[ "PRIVILEGE1" "PRIVILEGE2" ], "unionid":
* "o6_bmasdasdsad6_2sgVt7hMZOPfL" }
*/
logger.info("获取用户信息,getUserInfoJson=" + getUserInfoJson.toString());
/*
* end 获取微信用户基本信息
*/
// 获取到用户信息后就可以进行重定向,走自己的业务逻辑了。。。。。。
// 缓存 + 1
redisService.incr(ArtKey.isNum,"" + "1");
// 取缓存
String numStr = redisService.get(ArtKey.isNum, "" + "1", String.class);
model.addAttribute("name",getUserInfoJson.get("nickname"));
model.addAttribute("count",numStr);
// 回调到页面
return "index";
}
}public static final String APPID = "XXX";
// public static final String APPID = "XXX";
public static final String APPSECRET = "XXX";
// public static final String APPSECRET = "XXX";
// 与接口配置信息中的Token要一致
private static String token = "XXX";
public static JSONObject doGetJson(String url) throws ClientProtocolException, IOException {
JSONObject jsonObject = null;
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse response = client.execute(httpGet);
HttpEntity entity = response.getEntity();
if (entity != null) {
// 把返回的结果转换为JSON对象
String result = EntityUtils.toString(entity, "UTF-8");
jsonObject = JSON.parseObject(result);
}
return jsonObject;
}到这儿呢,第一个测试就能跑通了。
接下来,跑第二个测试

URL:(验证微信数字签名的接口)
Token:自己设置
@Slf4j
@RestController
@RequestMapping("/wechat")
public class WechatController {
/**
* 微信公众号签名认证接口
* @Title: test
* @Description: TODO
* @param: @param signature
* @param: @param timestamp
* @param: @param nonce
* @param: @param echostr
* @param: @return
* @return: String
* @throws
*/
@RequestMapping("/wxToken")
public String test(String signature,String timestamp,String nonce,String echostr) {
// 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
if (signature != null && WXAuthUtil.checkSignature(signature, timestamp, nonce)) {
return echostr;
}
return null;
}
}/**
* 验证签名
*
* @param signature
* @param timestamp
* @param nonce
* @return
*/
public static boolean checkSignature(String signature, String timestamp, String nonce) {
String[] arr = new String[] { token, timestamp, nonce };
// 将token、timestamp、nonce三个参数进行字典序排序
// Arrays.sort(arr);
sort(arr);
StringBuilder content = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
content.append(arr[i]);
}
MessageDigest md = null;
String tmpStr = null;
try {
md = MessageDigest.getInstance("SHA-1");
// 将三个参数字符串拼接成一个字符串进行sha1加密
byte[] digest = md.digest(content.toString().getBytes());
tmpStr = byteToStr(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
content = null;
// 将sha1加密后的字符串可与signature对比,标识该请求来源于微信
return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
}
/**
* 将字节数组转换为十六进制字符串
*
* @param byteArray
* @return
*/
private static String byteToStr(byte[] byteArray) {
String strDigest = "";
for (int i = 0; i < byteArray.length; i++) {
strDigest += byteToHexStr(byteArray[i]);
}
return strDigest;
}
/**
* 将字节转换为十六进制字符串
*
* @param mByte
* @return
*/
private static String byteToHexStr(byte mByte) {
char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
char[] tempArr = new char[2];
tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
tempArr[1] = Digit[mByte & 0X0F];
String s = new String(tempArr);
return s;
}
public static void sort(String a[]) {
for (int i = 0; i < a.length - 1; i++) {
for (int j = i + 1; j < a.length; j++) {
if (a[j].compareTo(a[i]) < 0) {
String temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
}第二个测试跑通了
,接下来就是公众号上的配置了。
参考:
https://www.zhongjianghua.com/att1tude/10205-2020-04.html
https://blog.csdn.net/qq_36654629/article/details/91877299
https://www.kanzhun.com/jiaocheng/534258.html
版权声明:本文为zy1104560031原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。