微信公众号开发-静默授权实现消息推送(微服务方式)
<p> 一:引用pom</p><div class="cnblogs_code">
<pre> <dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
<version>${weixin-java-mp.version}</version>
</dependency></pre>
</div>
<p> </p>
<p>二:获取code</p>
<p> 注意:redirect_uri 回调地址。请求完成后,微信在回调该地址的时候会带上code,然后根据code去拿openId。亲测不需要编码!!!</p>
<p> <span style="color: rgba(255, 0, 0, 1)"><strong>要在微信客户端打开接口地址</strong></span>,推荐工具https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1455784140 微信官方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("&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("&response_type=code&scope=snsapi_base&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编码失败:>>" +<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重定向失败:>>" +<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官网下载好客户端 http://www.ngrok.cc/download.html </p>
<p> <img src="https://img2018.cnblogs.com/blog/872836/201905/872836-20190516192227026-1081989426.png"></p>
<p> </p>
<p> 2)在官网注册账号并开通隧道 http://www.ngrok.cc 按官网教程开通,有免费隧道,完全可以满足本地开发使用。</p>
<p> 3)运行Sunny-Ngrok启动工具.bat 在命令行中输入 clientId (就是在官网注册的邮箱)和 隧道Id(看清,是Id 不是名字)</p>
<p> 4)成功后界面,恭喜你内网穿透已经做好,可以在外网环境访问你的服务接口了。</p>
<p> <img src="https://img2018.cnblogs.com/blog/872836/201905/872836-20190516192651882-1354990078.png"></p>
<p> </p>
<p> 2,配置微信授权域名</p>
<p> 1)微信公众平台 https://mp.weixin.qq.com/ </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]一定要都可以访问同,微信才能通过 redirect_uri 回调</p>
<p> <img src="https://img2018.cnblogs.com/blog/872836/201905/872836-20190516193955734-997847561.png"></p>
<p> </p>
<p> </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>"&secret="<span style="color: rgba(0, 0, 0, 1)">)
.append(</span>"726b163b73fe82a282903084805b663a"<span style="color: rgba(0, 0, 0, 1)">)
.append(</span>"&code="<span style="color: rgba(0, 0, 0, 1)">)
.append(code)
.append(</span>"&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> 在这里我们就能够拿到当前微信用户的openid 并在消息推送的时候进行用户 判断,来针对性的推送</p><br><br>
来源:https://www.cnblogs.com/scyr/p/10877610.html
頁:
[1]