十万天 發表於 2019-5-16 19:45:00

微信公众号开发-静默授权实现消息推送(微服务方式)

<p>  一:引用pom</p>
<div class="cnblogs_code">
<pre>    &lt;dependency&gt;
      &lt;groupId&gt;com.github.binarywang&lt;/groupId&gt;
      &lt;artifactId&gt;weixin-java-mp&lt;/artifactId&gt;
      &lt;version&gt;${weixin-java-mp.version}&lt;/version&gt;
    &lt;/dependency&gt;</pre>
</div>
<p>&nbsp;</p>
<p>二:获取code</p>
<p>  注意:redirect_uri 回调地址。请求完成后,微信在回调该地址的时候会带上code,然后根据code去拿openId。亲测不需要编码!!!</p>
<p>    &nbsp; &nbsp;<span style="color: rgba(255, 0, 0, 1)"><strong>要在微信客户端打开接口地址</strong></span>,推荐工具https://mp.weixin.qq.com/wiki?t=resource/res_main&amp;id=mp1455784140&nbsp;微信官方web开发工具。</p>
<p>  传入appId就行了,state是回调的时候带的参数</p>
<div class="cnblogs_code">
<pre>@ApiOperation(value = "获取code,并回调获取openId", notes = "获取code,并回调获取openId"<span style="color: rgba(0, 0, 0, 1)">)
@GetMapping(value </span>= "/routerForOpenId"<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> redirectToMyPage(HttpServletRequest request, HttpServletResponse response,
      String phone) {
    StringBuffer sb </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> StringBuffer();
    StringBuffer encodeUrl </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> StringBuffer(300<span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">公众号中配置的回调域名(网页授权回调域名)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">    String doname =
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">      request.getScheme() + ":</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">" + request.getServerName() + (-1 == request.getLocalPort() ? ""
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">            : ":" + request.getLocalPort());</span>
    String doname = "http://xuexing.ngrok.xiaomiqiu.cn"<span style="color: rgba(0, 0, 0, 1)">;
    String root </span>= "/WeChat"<span style="color: rgba(0, 0, 0, 1)">;
    String appId </span>= "wxb6fac4047e049312"<span style="color: rgba(0, 0, 0, 1)">;
    sb.append(</span>"https://open.weixin.qq.com/connect/oauth2/authorize?appid="<span style="color: rgba(0, 0, 0, 1)">);
    sb.append(appId);
    String url </span>= ""<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">对重定向url进行编码,官方文档要求</span>
      encodeUrl.append(doname).append(root).append("/openId.html"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">      url = URLEncoder.encode(encodeUrl.toString(), "utf-8");</span>
      sb.append("&amp;redirect_uri="<span style="color: rgba(0, 0, 0, 1)">).append(encodeUrl.toString());
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">网页授权的静默授权snsapi_base</span>
      sb.append("&amp;response_type=code&amp;scope=snsapi_base&amp;state="<span style="color: rgba(0, 0, 0, 1)">).append(phone);
      sb.append(</span>"#wechat_redirect"<span style="color: rgba(0, 0, 0, 1)">);
      response.sendRedirect(sb.toString());
    } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (UnsupportedEncodingException e) {
      log.error(</span>"重定向url编码失败:&gt;&gt;" +<span style="color: rgba(0, 0, 0, 1)"> e.getMessage());
      e.printStackTrace();
    } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) {
      log.error(</span>"response重定向失败:&gt;&gt;" +<span style="color: rgba(0, 0, 0, 1)"> e.getMessage());
      e.printStackTrace();
    }
}</span></pre>
</div>
<p>三:回调地址方法</p>
<p>  调用回调地址之前需要一些准备工作:</p>
<p>  1,回调地址需要做一个内网穿透,推荐工具Ngrok,花生壳。。本人使用的是Ngrok</p>
<p>    1)在Ngrok官网下载好客户端&nbsp;http://www.ngrok.cc/download.html&nbsp;&nbsp;</p>
<p>    <img src="https://img2018.cnblogs.com/blog/872836/201905/872836-20190516192227026-1081989426.png"></p>
<p>&nbsp;</p>
<p>    2)在官网注册账号并开通隧道&nbsp;http://www.ngrok.cc&nbsp; 按官网教程开通,有免费隧道,完全可以满足本地开发使用。</p>
<p>    3)运行Sunny-Ngrok启动工具.bat&nbsp; &nbsp;在命令行中输入 clientId (就是在官网注册的邮箱)和 隧道Id(看清,是Id 不是名字)</p>
<p>    4)成功后界面,恭喜你内网穿透已经做好,可以在外网环境访问你的服务接口了。</p>
<p>     <img src="https://img2018.cnblogs.com/blog/872836/201905/872836-20190516192651882-1354990078.png"></p>
<p>&nbsp;</p>
<p>  2,配置微信授权域名</p>
<p>    1)微信公众平台&nbsp;https://mp.weixin.qq.com/&nbsp;</p>
<p>    <img src="https://img2018.cnblogs.com/blog/872836/201905/872836-20190516192936161-1725208555.png"></p>
<p>    <img src="https://img2018.cnblogs.com/blog/872836/201905/872836-20190516193023867-826394081.png"></p>
<p>      <img src="https://img2018.cnblogs.com/blog/872836/201905/872836-20190516193229298-1676035204.png"></p>
<p>      <img src="https://img2018.cnblogs.com/blog/872836/201905/872836-20190516193628018-330869965.png"></p>
<p>     2)在保存的时候,会验证是否在你域名的根目录下保存了这个文件。事实上他验证的本质就是通过 [域名+/txt文件名] 是否能访问到txt文件中的字符码,所以我们在微服务中写一个接口将文件中字符返回出来,保存的时候就能校验通过了。</p>
<p>      注意:[域名+/txt文件名]和[域名+/openId.html]一定要都可以访问同,微信才能通过&nbsp;redirect_uri 回调</p>
<p>       <img src="https://img2018.cnblogs.com/blog/872836/201905/872836-20190516193955734-997847561.png"></p>
<p>&nbsp;</p>
<p>&nbsp;    </p>
<p>    </p>
<div class="cnblogs_code">
<pre>@ApiOperation(value = "回调获取openId", notes = "回调获取openId"<span style="color: rgba(0, 0, 0, 1)">)
@GetMapping(value </span>= "/openId.html"<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">发送请求,根据code获取openId</span>
<span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String getOpenId(HttpServletRequest request, HttpServletResponse response, String code,
      String state) {

    String content </span>= ""<span style="color: rgba(0, 0, 0, 1)">;
    String openId </span>= ""<span style="color: rgba(0, 0, 0, 1)">;
    String unionId </span>= ""<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">封装获取openId的微信API</span>
    StringBuffer url = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> StringBuffer();
    url.append(</span>"https://api.weixin.qq.com/sns/oauth2/access_token?appid="<span style="color: rgba(0, 0, 0, 1)">)
      .append(</span>"wxb6fac4047e049312"<span style="color: rgba(0, 0, 0, 1)">)
      .append(</span>"&amp;secret="<span style="color: rgba(0, 0, 0, 1)">)
      .append(</span>"726b163b73fe82a282903084805b663a"<span style="color: rgba(0, 0, 0, 1)">)
      .append(</span>"&amp;code="<span style="color: rgba(0, 0, 0, 1)">)
      .append(code)
      .append(</span>"&amp;grant_type=authorization_code"<span style="color: rgba(0, 0, 0, 1)">);

    ObjectMapper objectMapper </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ObjectMapper();
    </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
      HttpGet httpGet </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> HttpGet(url.toString());<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">这里发送get请求</span>
      HttpClient httpClient =<span style="color: rgba(0, 0, 0, 1)"> HttpClientBuilder.create().build();
      HttpResponse httpResponse </span>=<span style="color: rgba(0, 0, 0, 1)"> httpClient.execute(httpGet);
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 判断网络连接状态码是否正常(0--200都数正常)</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span> (httpResponse.getStatusLine().getStatusCode() ==<span style="color: rgba(0, 0, 0, 1)"> HttpStatus.SC_OK) {
      content </span>= EntityUtils.toString(httpResponse.getEntity(), "utf-8"<span style="color: rgba(0, 0, 0, 1)">);
      }
      Map map </span>= objectMapper.readValue(content, Map.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">);
      openId </span>= String.valueOf(map.get("openid"<span style="color: rgba(0, 0, 0, 1)">));
      unionId </span>= String.valueOf(map.get("unionid"<span style="color: rgba(0, 0, 0, 1)">));

      log.info(</span>"获取的openID:" +<span style="color: rgba(0, 0, 0, 1)"> openId);
      </span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">
       * 将openId保存到session中,当其他业务获取openId时,
       * 可先从session中获取openId.
       </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
      request.getSession().setAttribute(</span>"openId"<span style="color: rgba(0, 0, 0, 1)">, openId);
    } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (JsonParseException e) {
      log.error(</span>"json解析失败:"<span style="color: rgba(0, 0, 0, 1)">, e);
    } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (JsonMappingException e) {
      log.error(</span>"map转换成json失败:"<span style="color: rgba(0, 0, 0, 1)">, e);
    } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) {
      log.error(</span>"http获取openId请求失败:"<span style="color: rgba(0, 0, 0, 1)">, e);
    }
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> openId;
}</span></pre>
</div>
<p>&nbsp;在这里我们就能够拿到当前微信用户的openid 并在消息推送的时候进行用户 判断,来针对性的推送</p><br><br>
来源:https://www.cnblogs.com/scyr/p/10877610.html
頁: [1]
查看完整版本: 微信公众号开发-静默授权实现消息推送(微服务方式)