最近在做微信的企业服务号,刚开始通过个人的测试平台进行开发,使用了自定义菜单,自定义菜单包含两个功能:1、扫一扫,通过扫描我们账单的二维码,绑定账户和账单的关系;2、打开我们系统的账单查询页面,查询账户的账单信息。

  我的使用环境是:JSP+SpringMVC。

  开发之前需要首先配置服务好的JS接口安全域名:“公众号设置”-“功能设置”-“JS接口安全域名”。

  在测试号下测试运行没问题,实现方式是:扫一扫使用“scancode_waitmsg”类型,通过微信测试平台提供的“接口配置信息”配置的url回传扫描出的二维码信息,而打开网页采用自定义菜单的‘view’类型,通过menu配置的url打开网页。详细配置菜单如下:

{
"button":
[
{
"type": "scancode_waitmsg",
"name": "扫一扫",
"key": "MENU_BIND_CASE"
},
{
"type": "view",
"name": "我的账单",
"url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=#{appid}&redirect_uri=#{url}&response_type=code&scope=snsapi_base#wechat_redirect"
},
]
}

其中#{appid}和#{url}是我自己定制的参数占位符,发布的时候会通过代码的替换这两个占位符。

  当发布到正式服务号时,问题发生了,表现出的现象是:点击扫一扫菜单也能启动扫描二维码功能,扫描完成后也能看到访问等待的提示,但是服务器端拿不到微信端发送的任何二维码的信息。经过各种尝试后发现,服务号里边有个设置:“开发”-》“基本配置”-》“服务器配置”,这里如果配置后启用,则通过服务号的输入框输入的信息就能再次调用这个url来通知服务器输入的信息,但是带来的问题是自定义菜单没了!!!要想再次启用自定义菜单,就必须关掉这个配置!!!这个鱼与熊掌不能兼得的问题我没找到好的配置方式来解决,如果读者有好的方式希望能够分享给我,邮箱:cqu2005@163.com

  我解决这个问题的办法是:放弃使用菜单的“scancode_waitmsg”类型,统一改成“view”类型的菜单,然后通过自定义的界面中调用微信的JS-SDK的方式来完成扫一扫的功能。

{
"button":
[
{
"type": "view",
"name": "扫一扫",
"url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=#{appid}&redirect_uri=#{url.scan}&response_type=code&scope=snsapi_base#wechat_redirect"
},
{
"type": "view",
"name": "我的账单",
"url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=#{appid}&redirect_uri=#{url}&response_type=code&scope=snsapi_base#wechat_redirect"
},
]
}

  具体的过程:

,如果你需要返回提交的结果给用户,可以通过页面跳转的方式返回给用户,具体方法是在jsp中添加一个form,通过form提交(不再使用ajax异步提交)的方式完成页面的跳转。你也可以不通过页面提示给用户,而选择通过服务号对话框,发送消息给客户,类似于银行的信用卡消费提醒,实现这个功能你需要去申请自定义消息模版(防止企业号随意的给客户发广告骚扰客户),具体可以去看微信的帮助文档。

  下面就来具体的讲如何实现第二步的JS-SDK调用。

  首先、调用JS-SDK是需要通过微信验证的,建议您首先去查看微信的帮助文档;服务端首要要通过access_token获得jsapi_ticket,获取的方式参考access_token。以下主要说明一下wx.config()中的四个参数的由来:timestamp、nonceStr、signature、jsApiList;除了jsApiList外,其它的三个参数都是来自服务器端。

    1. timestamp:服务器端当前的时间,是一个long类型的数,时间单位精确到秒,如果是java下,通过System.currentTimeMillis()获得时间精确到毫秒,这时你需要除以1000才能使用;js端和服务端要保持一致;
    2. nonceStr:一个随机字符串,你可以每次都固定使用一个,也可以随机一个uuid使用,js和后端的值保持一致就行;
    3. singature:一个通过计算获得的加密字符串,加密算法为sha1,加密的文本为一个包含4部分的字符串(timestamp、noncestr、url、jsapi_ticket),其中noncestr需要注意名字大小写,与js的大小写不同!加密过程如下:a、获得当前的timestamp、noncestr、url、jsapi_ticket,然后将他们的变量名和值连接成“name=value”的字符串;(其中url为通过request请求获得字符串,具体参照实例代码,另外在jsp中通过alert这个属性也可以拿到url:location.href.split('#')[0])b、对连接后的四个字符串进行按照asc码升序排列,排列完成后将4个字符串通过连接符“&”连接为一个字符串;c、对连接后的字符串通过sha1加密并转换成16进制的字符串;d、将timestamp、noncestr、url、jsapi_ticket返回给jsp,传入给wx.config(),以备微信服务端验证。
    4. jsApiList:一个string类型的数组,内容为微信提供的功能识别关键字。

  然后、修改JSP页面,完成wx的config配置方法;

  最后、验证通过后系统会调用wx.ready()方法,通过本方法调用我们的扫一扫接口:wx.scanQRCode()完成扫描后通过ajax或者form提交的方式提交数据到指定的处理数据URL上,完成功能。

  实例代码如下:

  SpringMVC-Controller-字符串加密部分:

String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
String noncestr = UUID.randomUUID().toString();
String url = request.getScheme() + "://" + request.getServerName() + request.getServletPath();
if (request.getQueryString() != null) {
url += "?" + request.getQueryString();
}
String[] tempArr = { "jsapi_ticket=" + jsapi_ticket, "timestamp=" + timestamp, "noncestr=" + noncestr, "url=" + url };
Arrays.sort(tempArr);
String concatStr = tempArr[0] + "&" + tempArr[1] + "&" + tempArr[2] + "&" + tempArr[3];
String signature = DigestUtils.sha1Hex(concatStr);

  JSP-wx.config:

            wx.config({
debug: false,
appId: '${appId}',
timestamp: '${timestamp}',
nonceStr: '${noncestr}',
signature: '${signature}',
jsApiList: ['scanQRCode'] });

  JSP-wx.ready:

            wx.ready(function() {
wx.scanQRCode({
needResult: 1,
scanType: ["qrCode", "barCode"],
success: function(res) {
$('#content').val(res.resultStr);
$('#form1').submit();
}
});
});

  SpringMVC-Controller-获得二维码信息部分为一个普通的controller方法,这里不再描述。

  如果总是提示验证不同的问题,微信也提供了验证测试接口

  具体开发中你可能发现,整个过程并没有关于如何获得当前微信用户和我们自有网站账户的关联关系逻辑。其实这个问题的关键就是生成singature时的url,细心的人会发现这个url中有个code,可以通过这个code到微信服务器中拿到openid,再通过openid获得我们系统的userid,由于篇幅原因不再细说,具体可以参考我的另一篇文章(如何通过用户点击自定义菜单的view类型标签获得所绑定的系统用户)。

关于微信中JS-SDK的接口验证过程详细说明的更多相关文章

  1. 微信企业号JS SDK

    微信企业号JS SDK <?php define('CorpID', "wx82e2c31215d9a5a7"); define('CorpSecret', "&q ...

  2. [微信JSSDK] 解决SDK注入权限验证 安卓正常,IOS出现config fail

    实测有效 解决微信游览器和企业微信游览器JSSDK注入权限验证 安卓正常,IOS出现config fail 一开始我们想到的是可能微信这边的Bug,但细想一下应该不是.因为可能涉及到了IOS的底层原理 ...

  3. 微信前端js sdk以外的开发

    此时页面中就会出现刚才我画红圈部分的工具条. 这个工具条再加上上面的标题栏工具条. 极大的降低了可视区域的面积. 是否能将它去掉呢?答案是能够的.增加以下代码就能够去掉微信中以下的工具条: docum ...

  4. Android应用之——微信微博第三方sdk登录分享使用过程中的一些常见问题

    前言 近期在使用第三方登录和分享的过程中遇到了非常多问题,一方面能够归结为自己经验的不足,还有一方面事实上也说明了官方文档的含糊不清.这篇博文不会写关于怎样使用第三方登录分享,由于官方文档已经写明了步 ...

  5. 调用微信js sdk

    场景:需要调用微信获取当前位置的借口. 途径:查看微信 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115 .后 ...

  6. 微信js SDK接口

    微信JS-SDK说明文档 http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html 一.微信登录功能 在进行微信OAut ...

  7. 微信JS SDK配置授权,实现分享接口

    微信开放的JS-SDK面向网页开发者提供了基于微信内的网页开发工具包,最直接的好处就是我们可以使用微信分享.扫一扫.卡券.支付等微信特有的能力.7月份的时候,因为这个分享的证书获取问题深深的栽了一坑, ...

  8. 微信JS SDK接入的几点注意事项

    微信JS SDK接入,主要可以先参考官网说明文档,总结起来有几个步骤: 1.绑定域名:先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”.备注:登录后可在“开发者中心”查看对 ...

  9. 微信js sdk上传多张图片

    微信js sdk上传多张图片,微信上传多张图片 该案例已tp3.2商城为例 直接上代码: php代码: public function ind(){ $appid="111111111111 ...

随机推荐

  1. CSS Outline(轮廓)

    CSS Outline(轮廓) 一.CSS 轮廓(outline) 轮廓(outline)是绘制于元素周围的一条线,位于边框边缘的外围,可起到突出元素的作用. CSS outline 属性规定元素轮廓 ...

  2. javascript 面向对象 new 关键字 原型链 构造函数

    JavaScript面向对象JavaScript 语言使用构造函数(constructor)作为对象的模板.所谓"构造函数",就是专门用来生成实例对象的函数.它就是对象的模板,描述 ...

  3. zookeeper可视化管理工具node-zk-browser安装

    一.安装nodejs 1. 下载 wget https://github.com/joyent/node/archive/v0.10.35.tar.gz 2. 解压 3. 安装依赖 yum -y in ...

  4. Learning Phrase Representations using RNN Encoder–Decoder for Statistical Machine Translation

    1.主要完成的任务是能够将英文转译为法文,使用了一个encoder-decoder模型,在encoder的RNN模型中是将序列转化为一个向量.在decoder中是将向量转化为输出序列,使用encode ...

  5. 在VMware中使用Nat方式设置静态IP

    为了在公司和家中不改变ip,所以采用vm的NAT模式来设置静态ip 1.vm采用NAT模式联网 2.编辑vm虚拟机设置 3.查看该网段的网关 可以看出网关为192.168.44.2,然后开始设置静态i ...

  6. 20145335郝昊《java程序设计》第7周学习总结

    20145335郝昊 <Java程序设计>第7周学习总结 教材学习内容总结 认识时间与日期 格林威治标准时间:简称GMT时间,参考格林威治皇家天文台的标准太阳时间. 世界时:简称UT,借由 ...

  7. 彻底搞懂hashCode与equals的作用与区别及应当注意的细节

    以前写程序一直没有注意hashCode的作用,一般都是覆盖了equals,缺没有覆盖hashCode,现在发现这是埋下了很多潜在的Bug!今天就来说一说hashCode和equals的作用. 先来试想 ...

  8. linux下如何获取sd卡中的mbr

    答:使用dd命令,示例如下: dd if=/dev/mmcblk0 of=mbr.bin bs=512 count=1 解析: bs表示指定输入输出的块大小为512个字节 count表示指定读取输入的 ...

  9. Django安装及创建工程

    Django MTV模型介绍 Django的MTV分别代表: Model(模型):负责业务对象与数据库的对象(ORM) Template(模版):负责如何把页面展示给用户 View(视图):负责业务逻 ...

  10. jackson序列化字段字母大小写及字段名重复

    一:Jackson默认的属性发现规则将会查找到如下所述的属性: 1.所有被public修饰的字段(成员变量): 2.所有被public修饰的getter(即形如“getXxx()”的方法): 3.所有 ...