最近在做微信的企业服务号,刚开始通过个人的测试平台进行开发,使用了自定义菜单,自定义菜单包含两个功能: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. mysql left join中where和on条件的区别

    left join中关于where和on条件的几个知识点: 1.多表left join是会生成一张临时表,并返回给用户 2.where条件是针对最后生成的这张临时表进行过滤,过滤掉不符合where条件 ...

  2. @component的注解

    1.@controller 控制器(注入服务) 2.@service 服务(注入dao) 3.@repository dao(实现dao访问) 4.@component (把普通pojo实例化到spr ...

  3. 访问ashx一般应用程序

    浏览器中的地址栏键入要访问页面的地址:回车(是和服务器软件打交道)----向服务器发送请求(以http协议为基础,服务器按照此协议解释理解接收到的数据),服务器接收到发送的请求,根据请求信息知道当前所 ...

  4. git分支合并脚本

    为什么要写这个脚本 工作中经常会有合并分支的操作,一开始也不以为然,后来发现如果更新频繁的话,根本就停不下来,昨天上午正好有空,就完成了下面的这个初版 可能存在的问题 一般的应用场景都是:从maste ...

  5. LeetCode——merge-two-sorted-lists

    Question Merge two sorted linked lists and return it as a new list. The new list should be made by s ...

  6. 修改主机hosts文件 访问外网

    参考:详解google Chrome浏览器(理论篇) 感谢原博主 Alan_beijing 的分享,博客:Alan_beijing hosts文件所在位置: a.Windows系统: C:\Windo ...

  7. 【乱码】Request QueryString 编码,传值乱码的几种情况和解决办法(单页,多页)

    自己的项目还好,合作接口神马的传值乱码是很常见的. 遇到了几次这种恶心情况,积累了一点经验,有不对的地方欢迎指正. 乱码原因: 一般来说,常用的编码不是utf-8就是gb2312,一样的 HttpUt ...

  8. u-boot-2015.07 make xxx_config 分析

    1.u-boot编译脚本:mk.sh #! /bin/sh export PATH=$PATH:/opt/ti-sdk-am335x-evm-08.00.00.00/linux-devkit/sysr ...

  9. java_zlib_资料

    1.网页资料 1.1.http://bbs.csdn.net/topics/190020986 1.2. http://cdn.verydemo.com/demo_c89_i166794.html h ...

  10. 实现Runnable和继承Thread的区别

    啥都先不说,运行两段程序看看结果再分析 实现Runnable接口的程序代码 public class ThreadTest1 implements Runnable { private int num ...