抛砖微信公众号应用开发

现在微信营销,真是炙手可热,各行各业都在利用微信这个社交平台,基于微信服务器这个服务网关,开发自己的应用服务,通过微信进行传播,真是方便快捷高效!大体的通信架构如下图所示。

由于工作的需要,我也着手研究微信公众平台的开发,在这过去的一周的时间,折腾了一个小实验环境,打通微信的两个基本验证关卡。

第一道验证,就是URL,Token填写完成后,点击提交的过程。(后面会详述)

第二道验证,就是公众号服务器上面的帖子进行分享等操作时,为了让别人看到友好的“标题”+“描述”+“缩略图”这种模式的帖子,必须在待分享的web页面中通过jssdk的使用,提供jsapi_ticket, timestamp, nocestr以及signature到微信服务器,让其验证,通过才会得到友好的转帖,否则就是没有缩略图,只有一个链接的丑陋格式的帖子。(后面详述)

为了将砖抛的好,有价值,我就通过微信公众号测试平台,如何获取appid及appsecret开始说吧。首先通过http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login这个链接,用手机微信扫一扫,即可登录获得一个测试平台的appid以及appsecret秘钥。

完成了这步后,接下来,就是我们要开发后台web应用了,对应架构图中的business server部分的后台程序的开发了。这个开发,主要完成上面说的两步验证,第一步验证相对来说简单,基本不涉及实际的业务,第二步的验证,主要是帖子的转发,微信服务器为了确保帖子是基于jssdk来开发的(要通过微信服务器的验证),才能给予友好的转发格式

先说第一步验证,主要目的是让微信服务器知道它即将把一个微信用户的信息转发到一个可信的后台开发者服务器(business server)。如下图,我的测试平台中,business server的URL,以及对应得Token。URL是告知微信服务器,这个business server的地址。Token,这个是用来生成签名用的,在这一步验证中非常重要。business server的验证程序中生成签名的函数中用到的token必须和这里填写的一样。【说白了,就是微信服务器通过下图中配置的token,再结合其他约定好的参数按照一定的算法生成签名,将签名及参与计算的其他参数(timestamp, nonce)发给business server, business server也用同样的方式生成签名,最后在business server端比较自己生成的签名和微信服务器发来的签名是不是一样】

如何才可信呢?微信服务器在第一次与后台开发者服务器(business server)通信时会将signature, timestamp,nonce,echostr者四个字符串通过一个http GET请求发给business server。business server在收到这四个信息时,通过一定的规则(token, timestamp, nonce这三个变量名全小写按照字典序排序后,拼接成一个字符串后通过SHA1算法生成签名)生成签名,和收到的签名比对,不相等,则拒绝响应请求(防止business server被恶意攻击)。签名相同后,将echostr字符串返回给微信服务器,则完成了第一步的验证。

验证通过后,你会看到下面的提示:

若验证没有通过,你会看到下面的提示:

失败的情况,若保证签名函数处理没有错的话,很可能是URL写的不对,一定是对应处理第一步签名这个controller的URL。另外一个,就是token的不一致。business server中计算签名用的Token一定是和这里配置的一致。

下面,说说第二步验证,主要是涉及到js页面操作的验证,也就是涉及到调用jssdk中api函数的验证了。这个验证过程和前面说的验证过程是反的,这里,是business server将签名(signature)计算出来后,配合appid, timestamp, noncestr, jsapi_ticket发给微信服务器。微信服务器同样会利用收到的jsapi_ticket, timestamp, noncestr,以及当前web页面对应的URL,按照全小写字母,且字典序排序后,以下面的格式组成一个字符串,并SHA1加密生成密钥,两个密钥相等,则验证通过,否则失败。

1 //注意这里参数名必须全部小写,且必须有字典序
2 string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str +  "&timestamp=" + timestamp + "&url=" + url;

对于第二步,还必须说明一定,business server计算签名的过程:

1> 通过appid以及appsecret,替换https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET中的APPID以及APPSECRET,然后通过http get发给微信服务器,得到Access Token。

2> 通过获取的Access Token,替换https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi中的ACCESS_TOKEN,然后通过http get发送给微信服务器,得到jsapi_ticket.

这两个步骤,一定要用https,得到的数据都是有时间期限的,都是7200秒。而微信的这两个接口每天是有调用次数限制的(2000),所以,一定要缓存这两个数据。不要每次都从微信服务器取。否则影响应用的可用性,好一点的情况下,web应用的性能也不会很好,比较慢啊!

缓存的工具很多,spring有cache及encache,不过我没有选择,我选择的是Google guava cache,用起来简单,主要是比较习惯和熟练吧。下面是基本的代码:

 1 package com.tkiilab.utils;
 2
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 import java.util.concurrent.ExecutionException;
 6 import java.util.concurrent.TimeUnit;
 7
 8 import org.slf4j.Logger;
 9 import org.slf4j.LoggerFactory;
10
11 import com.google.common.cache.CacheBuilder;
12 import com.google.common.cache.CacheLoader;
13 import com.google.common.cache.LoadingCache;
14 import com.tkiilab.model.AccessToken;
15
16 public class TokenJsapiHolder {
17
18     private  final static Logger logger = LoggerFactory.getLogger(TokenJsapiHolder.class);
19
20     private static TokenJsapiHolder instance = new TokenJsapiHolder();
21
22     private LoadingCache<String, List<String>> cache;
23
24     private TokenJsapiHolder(){
25         cache = CacheBuilder.newBuilder().maximumSize(5)
26                                          .refreshAfterWrite(7000, TimeUnit.SECONDS)
27                                          .build(new CacheLoader<String, List<String>>() {
28                     @Override
29                     public List<String> load(String appid) throws Exception {
30
31                         AccessToken token = WeixinUtil.getAccessToken(Constants.APPID, Constants.SECRET);
32                         if(token != null){
33                             String jsapi_ticket = WeixinUtil.getJsApiTicket(token.getAccessToken());
34                             List<String> tokenJsapi = new ArrayList<String>();
35                             String access_token = token.getAccessToken();
36                             tokenJsapi.add(access_token);
37                             tokenJsapi.add(jsapi_ticket);
38
39                             logger.info("Access token: " + access_token);
40                             logger.info("Jsapi ticket: " + jsapi_ticket);
41                             return tokenJsapi;
42                         }
43                         return null;
44                     }
45
46                 });
47     }
48
49     public static TokenJsapiHolder getInstance(){
50         return instance;
51     }
52
53     private LoadingCache<String, List<String>> getCache(){
54         return cache;
55     }
56
57     public String getTokenOrJsapi(CertWxCacheable type){
58         try {
59             return instance.getCache().get("TOKEN_TICKET").get(type.ordinal());
60         } catch (ExecutionException e) {
61             e.printStackTrace();
62         }
63         return null;
64     }
65
66 }

其他的,没有什么好多说的了,个人觉得,微信开发,开发环境非常重要。公司内的网络,权限管理很死板。所以,测试的时候,将后台服务应用部署到sina app engine的云服务器上,因为微信的接口访问到我们的应用服务,必然要求我们的应用程序是能够被外网访问的。所以,debug起来就是个问题。。。

新浪的云服务器,个人觉得性能不行,甚至可靠性都存在问题,至少它的低配云服务器是如此的差。而且我的程序部署在其上,测试第二步的验证逻辑时,总是失败,Access Token总是无法获取。

后来,经过好友张龙的推荐,发现了一款反向代理软件ngork,真是牛逼到爆了。下面简单的说下,我用的这个款,http://natapp.cn/,可以在这个网站下载,也有使用说明,非常简单。下载解压后,只有三个文件,ngork.cfg, ngork.exe, run.bat。(我是在windows下使用的,当然根据自己的需求,选平台)。

下面是我在我本地电脑上测试微信公众号后台应用程序时配置的run.bat的内容:

1 ngrok -config ngrok.cfg -subdomain iismaster 8080

其他的,我们都不需要改,也不用关心,毕竟一个工具而已,只需要知道如何用即可。重点是要适配自己的应用程序名以及开发环境的端口。比如我得应用程序名称是iismaster,我的web应用部署在本地的tomcat上,默认的端口号是8080,所以这里,绿色的部分写8080,最终对外访问时,ngrok默认都是映射成80端口,这个符合微信接口的要求。

使用时,cmd到ngork软件解压缩后的目录,直接运行run.bat即可。

下面是我得run.bat运行的日志:

这里,对于如何使用ngrok,主要是在配置微信公众号平台时填写的URL,及js安全域名(若有需要时),一定要填写上面Forwarding对应的URL及应用名及path信息。因为这里的映射,比如上面的http://iismaster.ngrok.natapp.cn,其实对应在本地debug时是http://localhost:8080,所以,部署在tomcat中运行时,访问path为/hello对应的结果时,全URL是http://localhost:8080/iisMaster/hello, 在ngrok启用的情况下,URL为http://iismaster.ngrok.natapp.cn/iisMaster/hello.

注意,若这个URL的映射关系没弄清楚,404的错误是难免的哟,你懂的!

Ok,到此结束,微信开发的基本逻辑抛砖完成,其中有两个痛点,一个是对两个验证的理解,尤其是第二步验证,重点注意参与计算签名的url一定是当前要分享等jssdk涉及的页面的url。 另外的一个痛点,就是环境,特指debug,这里ngrok真是神器!

时间: 2024-12-11 15:32:37

抛砖微信公众号应用开发的相关文章

微信公众号退款开发

博主是小菜鸟,这篇文章仅是自己开发的随笔记录,不足博友可以指出来,一起进步 1.[微信支付]公众号支付开发者文档链接地址 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4 调用微信退款接口,需要发送特定的xml格式字符串到到微信退款接口: 2.微信申请退款需要双向证书, JAVA只需要使用apiclient_cert.p12即可,证书从 https://pay.weixin.qq.com/index.php/core/hom

微信公众号支付开发全过程 --JAVA

按照惯例,开头总得写点感想 ------------------------------------------------------------------ 业务流程 这个微信官网说的还是很详细的,还配了图.我还要再说一遍. 用户点击一个支付按钮-->{后台一大推处理}-->用户看到了一个输入密码的界面,包含金额等一些信息-->用户输入密码后出来一个支付成功的页面(这部分流程都是微信自己完成的,我们什么都不用做)-->返回系统自己的页面(总不能让用户一直看着一个支付完成的页面吧

C#/ASP.NET MVC微信公众号接口开发之从零开发(二) 接收微信消息并且解析XML(附源码)

文章导读: C#微信公众号接口开发之从零开发(一) 接入微信公众平台 微信接入之后,微信通过我们接入的地址进行通信,其中的原理是微信用户发送消息给微信公众账号,微信服务器将消息以xml的形式发送到我们的绑定的地址上,通过解析XML数据,获取到微信用户发送的消息,让根据微信消息(文本:关键字,图片,语音等等)回复XML格式的数据给微信服务器,微信服务器再将接收到的消息返回给用户微信. 我们所需要做的:接收消息和返回消息 一.创建实体类 首先看文档http://mp.weixin.qq.com/wi

C#/ASP.NET MVC微信公众号接口开发之从零开发(三)回复消息 (附源码)

C#/ASP.NET MVC微信接口开发文章目录: 1.C#/ASP.NET MVC微信公众号接口开发之从零开发(一) 接入微信公众平台 2.C#/ASP.NET MVC微信公众号接口开发之从零开发(二) 接收微信消息并且解析XML(附源码) 一.拼凑回复的XML字符串 微信被动回复的形式有一下六种: 1 回复文本消息 2 回复图片消息 3 回复语音消息 4 回复视频消息 5 回复音乐消息 6 回复图文消息 分别对应不同的XML形式,这里以文本消息和图文为例,读者举一反三其他的类似,不再赘述:

C#微信公众号接口开发,灵活利用网页授权、带参数二维码、模板消息,提升用户体验之完成用户绑定个人微信及验证码获取

一.前言 当下微信公众号几乎已经是每个公司必备的,但是大部分微信公众账号用户体验都欠佳,特别是涉及到用户绑定等,需要用户进行复杂的操作才可以和网站绑定,或者很多公司直接不绑定,而是每次都让用户填写账号密码.作为微信接口开发人员我们知道网页授权可以用作微信网页用作安全登录,带参数二维码的使用用作记录用户来源,模板消息用作购物消费等消息的通知,但是很少看到有综合利用这些高级接口做出体验比较好的公众账号,这里分享一些我开发的用户绑定和验证码的一些心得.所需要的接口有基础的回复.网页授权.带参数二维码.

Python微信公众号后台开发&lt;003&gt;:自定义菜单

有同学问道微信公众号后台开发的自定义菜单怎么实现? 这个问题本来想放到后面的,因为的确对公众号的影响挺明显的, 因为开启后台服务,公众号的自定义菜单就不见了,很影响使用, 也有同学问这个问题,就提前了,后面如果有进展会进行更新. 开发文档: https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Explanation_of_interface_privileges.html 订阅号账号分类及权限 订阅号分为个人号和企业订

使用开源库MAGICODES.WECHAT.SDK进行微信公众号支付开发

概要 博客使用Word发博,发布后,排版会出现很多问题,敬请谅解.可加群获取原始文档. 本篇主要讲解微信支付的开发流程,相关业务基于MAGICODES.WECHAT.SDK实现.通过本篇教程,您可以很方便的快速完成微信公众号支付的开发. 关于Magicodes.WeChat.SDK MAGICODES.WECHAT.SDK为心莱团队封装的轻量级微信SDK,现已全部开源,开源库地址为:https://github.com/xin-lai/Magicodes.WeChat.SDK 更多介绍,请关注后

微信公众号支付开发

最近做了公众号支付,从无到有.大概经历如下步骤: 开发环境 VS2015 W10 .NET4.6 一.公众号 客户公司没有公众号,也不会申请.于是打开微信公众号介面,告诉它一步步弄.最后申请了一个服务号,并且提交了认证申请.其中大概有几处注意 : 微信号公众号名字(这个有被占用的情况).认证时提交的身份信息,企业的三证合一拍照上传. 认证申请提交后第3天时通过了,然后进入微信号开通支付功能,这个是指公众号的支付功能.过程中需要绑定银行帐号,选择经营项目,注意各项目营收费率不一样,经营资质拍照上传

微信公众号如何开发

公司年会刚过,在杭州黄龙体育场举行的,场面非常震撼,妹子性感,富有活力.公司领导愿景十分远大.自己作为一线员工不仅震撼吗,更多的是一种渺小. 第二天事业部年会,场面和公司年会比起来小了很多,晚上抽奖环节十分火热.奖品到是没有中上,但是对于抽奖软件十分感性趣. 抽奖软件是嵌入在微信里面,从微信公众号里面可以添加.有摇一摇的功能,摇的最厉害的的人第一名的会获奖.还有一个吐槽墙的功能,这个模块可以发送信息到屏幕上,比如,求妹子,求包养等等任何信息和表情都可以发送到这个屏幕上面,定时刷新屏幕.软件业务不