最近公司需要进行微信公众号开发,要求微信用户点进公众号直接登录,在实现此功能的过程中,遇见了一些坑,写出来记在这里
具体文档信息如下两个链接,openId是获取unionId的前提
获取用户openId及unionId:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842
根据openId获取用户unionId:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140839
经过梳理发现,同一个公司如果拥有不同的公众号、小程序....,同一个微信用户相对于这些公众号、小程序....的openId都是不同的,此时需要我们申请一个微信开放平台账号,用这个微信开放平台账号把这些公众号、小程序....绑定起来,同一个微信用户相对于同一个开放平台下的公众号、小程序...就有着完全相同的unionId了,这样可以实现,一个公司下的多公众号..之间的用户衔接。
微信开放平台:https://open.weixin.qq.com
在贴代码之前,把遇见的坑写在前面:
1. 使用如下链接获取unionId,在获取unionId时,报错:
{"errcode":40001,"errmsg":"invalid credential, access_token is invalid or not latest hint: [D_K0881vr49!]"}
官方文档如下:
注意这里的access_token其实是基础access_token。注意access_token需要做一下缓存,这里官方文档中有进行说明。我使用了redis进行缓存
获取基础access:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183
2. 如果使用如下链接进行unionId的获取,不要忘记,scope应为 snsapi_userInfo
3. 因为我使用了第一种方法,所以再说说第一种里面注意要点
(1)不要忘记把公众号绑定到开放平台,不然获取不到用户信息,包括unionId
(2)如果scope为snsapi_base ,一定要微信用户关注了此微信公众号,不然也获取不到unionId
(3)如果scope为snsapi_userinfo,那么用户授权允许之后,无论是否关注此微信公众号,都可以获取到unionId
贴代码:需要前端把code给我
public Result loginByOpenId(@RequestParam String code) {
String access_token;//token
String openId;//openid
String UnionID;//UnionID
Integer expires_in;//token 过期时间
//校验数据的合法性,是否为空
if (StringUtils.isBlank(code)) {
throw new ServiceException(MemberCodeConstant.USER_EMPTY);
}
//调用微信接口获取
RestTemplate restTemplate = new RestTemplate();
//获取openId
String httpOpenIdUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + fuwuAppid + "&secret=" + fuwuSecret + "&code=" + code + "&grant_type=authorization_code";
ResponseEntity response = restTemplate.getForEntity(httpOpenIdUrl, String.class);
if (200 != response.getStatusCodeValue()) {
logger.error("请求失败,获取openId失败");
throw new ControllerException(MemberCodeConstant.ACCESS_TOKEN_GET_FAIL);
}
String r = response.getBody();
JSONObject body = JSONObject.parseObject(r);
if ((Integer) body.get("errcode") != null) {
logger.error("请求成功,但是获取openId失败,错误码:" + body.get("errcode"));
throw new ControllerException(MemberCodeConstant.ACCESS_TOKEN_GET_FAIL);
}
//网页授权token 不一定能用得上
//access_token = (String) body.get("access_token");
openId = (String) body.get("openid");
//获取基础access_token
try (Jedis jedis = jedisPool.getResource()) {
jedis.select(CommonConstant.REDIS_YANCODE);
access_token = jedis.get("access_token");
/** 不存在则重新去请求*/
if (StringUtils.isBlank(access_token)) {
//获取access_token
String httpTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + fuwuAppid + "&secret=" + fuwuSecret;
ResponseEntity