微信公众号使用包括认证以及获取openID

2020年5月18日 作者 陈益

一、启用公众号

访问:https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=2132071945&lang=zh_CN

输入开发账号密码后

AppID  wxb2e07f6a9f25c67d

    AppSecret 83bfd2e25f8cd2072775113a4d494307 获取Token String tokenUrl = MessageFormat.format( "https://api.weixin.qq.com/cgi-bin/token?
				grant_type={0}&appid={1}&secret={2}", "client_credential", "wx36ce773b1d71955c", "92b04c7c0b6cbbbd249835e74d04f218"); 响应: {"access_token":"33_6D_o4KXMX16qJZzjIO-T_-KcoTv-GwKtn96uBj1XRRKNo6tF1xYLMcmXYpycqw1Maobxdju80uWzuqexblG4QneqvBfizBeSFA1IyFDOpl10DlgVklPByQCFcuoRP1NfBocHrt2x1UjxYf7oICMdAEACWG","expires_in":7200}

二、(附加功能)设置服务器认证用来获取所有的用户,在微信中是无法使用微信账号定位具体的某一个人,只能使用openid和UnionID,它们的区别:

获取用户基本信息(UnionID机制)

在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的。对于不同公众号,同一用户的openid不同)。公众号可通过本接口来根据OpenID获取用户基本信息,包括昵称、头像、性别、所在城市、语言和关注时间。

请注意,如果开发者有在多个公众号,或在公众号、移动应用之间统一用户帐号的需求,需要前往微信开放平台(open.weixin.qq.com)绑定公众号后,才可利用UnionID机制来满足上述需求。

UnionID机制说明:

开发者可通过OpenID来获取用户基本信息。特别需要注意的是,如果开发者拥有多个移动应用、网站应用和公众帐号,可通过获取用户基本信息中的unionid来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号,用户的unionid是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,unionid是相同的。

获取用户基本信息(包括UnionID机制)

开发者可通过OpenID来获取用户基本信息。请使用https协议。

接口调用请求说明 http请求方式: GET https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

根据OpenID就可以获取用户的基本信息没有 无法获取微信号 ,此接口可以查看当前公众号有多少人和昵称

三、发送客服消息

发送客服消息需要确定客户的OpenID,那么怎么获取OpenID ,这里总结业务流程。

  1. 当客户关注公众号,会触发事件推送,如果你想关注的时候就回复欢迎语等,那么你需要关注事件推送的,路径:开发->基本配置->填写服务器配置https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_event_pushes.html

  2. 如果在使用过程中主动发送消息,怎么获取OpenID,这个时候需要先客户的openID关联在我们系统,然后根据用户信息获取该openID字段这就是核心,具体方法

    1. 用户点击微信公众号的具体的某个菜单,激发授权动作。此授权是oauth2认证的,所以在配置菜单中是使用连接:功能->自定义菜单->菜单内容->跳转网页,这个网页的地址填写跳转我们网站上,例如:http://cn.toppgo.com/oAuth2Api/auth?state={“service”%3A”wechatPublicAuthService”%2C”hostName”%3A”http%3A%2F%2Fcn.toppgo.com”%2C”redirectUrl”%3A”http%3A%2F%2Fcn.toppgo.com%2Fapp%2Flogin.html”%2C”scope”%3A”snsapi_userinfo”}
    2. 当用户点击之后,会跳转至我们后台服务器会生成一个新的地址使用302配合location进 行跳转到腾讯的认证上:https://open.weixin.qq.com/connect/oauth2/authorize?appid=” + APPID + “&redirect_uri={0}&scope={1}&state={2}
    3. 因上述连接中存在redirect_uri,那么服务器授权之后会跳转我们预定callback地址中来,那么开始获取code,根据code获取token:https://api.weixin.qq.com/sns/oauth2/access_token?appid=” + APPID + “&secret=” + APP_SECRET + “&code={0}&grant_type=authorization_code
    4. 上述拿到token之后,就可以获取用户的信息了。 https://api.weixin.qq.com/sns/userinfo?access_token={0}&openid={1}&lang=zh_CN
    5. 将第四步获取的用户的信息包括openID之后,添加到地址参数中然后跳转到绑定我们的页面
        String token = tokenMap.get("access_token");    
        String userInfo = JsoupUtils.getDocumentUseGet(MessageFormat.format( "https://api.weixin.qq.com/sns/userinfo?access_token={0}&openid={1}&lang=zh_CN", token, APPID));   
         String redirectUrl = oAuthApiDto.getRedirectUrl();      Map<String, String> userInfoMap = JSONObject.parseObject(userInfo, Map.class);    
         List<String> queryParams = Lists.newArrayList();     for (Map.Entry<String, String> entry : userInfoMap.entrySet()) {
    	    queryParams.add(MessageFormat.format("{0}={1}", entry.getKey(), entry.getValue()));     }
    	httpServletResponse.setStatus(HttpStatus.SC_MOVED_TEMPORARILY);          String encodeQuery = UriUtils.encodeQuery(StringUtils.join(queryParams, "&"), "utf-8");    
         httpServletResponse.setHeader("location", MessageFormat.format("{0}?{1}", redirectUrl, encodeQuery)); 
    1. 在我们信息绑定页面中,让客户绑定用户信息且关联上述的OpenID,后期根据用户在我们系统的信息反查询openId进行消息发送
  3. 消息发送:

String tokenUrl = MessageFormat.format("https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={0}",
				accessToken); JSONObject jonJsonObject = new JSONObject();  jonJsonObject.put("touser", 从上面中反查询openID); jonJsonObject.put("msgtype", "text"); JSONObject textJSONObject = new JSONObject();  textJSONObject.put("content", "很高兴您关注Toppgo,当前时间:"+new Date().toLocaleString()); jonJsonObject.put("text", textJSONObject); Document reDocument = JsoupUtils.getDocumentForRequestBody(tokenUrl, "application/json;charset=utf-8", jonJsonObject.toString(), null); System.out.println(reDocument.body().html()); 
  1. 当客户取消关注的时候,关注推送事件,获取该OpenId,更改db中的数据,将我们DB中的该字段置空。