.
作者 : 万境绝尘
转载请注明出处 :http://blog.csdn.net/shulianghan/article/details/20494177
.
GitHub源码位置:
--HTTP:https://github.com/han1202012/WeChatVerify.git
--SSH:git@github.com:han1202012/WeChatVerify.git
CSDN下载认证程序的war包和源码:http://download.csdn.net/detail/han1202012/6999207
微信验证war包下载:
--访问地址:ip地址:80/WeChatVerify/verifyServlet ;
--Token: 注意Token是 "hanshuliang" ;
一. 开启开发模式解析
1. 开发者文档
首先进入编辑模式, 将编辑模式关闭, 进入开发模式 :
点击查看文档, 就可以打开微信的开发者文档 : 路线 功能 -> 高级功能 -> 开发模式 -> 查看文档 ;
开发者文档目录结构说明 :
-- 新手接入 : 包括 接入指南 典型案例介绍 开发者规范, 讲解如何接入开发者模;
-- 基础支持 : 包括 获取access_token 全局返回码说明 接口频率限制说明 上传下载多媒体文件;
-- 接收消息 : 包括 验证消息真实性 接收普通消息 接收事件推送 接收语音识别结果;
-- 发送消息 : 包括 发送被动响应消息 发送客服消息;
-- 用户管理 : 包括 分组管理接口 获取用户基本信息 获取关注者列表 获取用户地理位置 网页授权用户基本信息 网页获取用户网络状态;
-- 自定义菜单 : 包括 自定义菜单创建接口 自定义菜单查询接口 自定义菜单删除接口 自定义菜单事件推送;
-- 推广支持 : 包括 生成带参数的二维码 ;
-- 微信 JS接口 : 包括 隐藏微信中网页右上角的按钮 隐藏微信中网页底部的导航栏 网页获取用户网络状态;
-- 开发者交流互助 : 包括 开发者问答系统 接口调试工具 接口体验测试号申请;
2. 开发者校验流程解析
(1)申请消息接口
点击开发模式 "成为开发者" 按钮之后, 会弹出协议 :
之后会弹出填写 URL 和 Token :
-- URL : 用来接收微信服务器数据的接口URL;
-- Token : 任意填写, 用于生成签名;
(2) 验证URL有效性
校验流程 : 程序必须能够处理HTTP GET请求, 并对请求者身份进行校验, 确保请求来自微信服务器;
-- 获取参数 : HTTP GET 会携带四个参数 signature timestamp nonce echostr;
-- 拼装参数 : 将排序后的三个参数按照字典顺序排成字符串;
-- 加密参数 : 将排序后的字符串进行sha1加密;
-- 返回结果 : 将加密后的字符串 与 signature 参数对比, 如果相等则说明请求来自微信服务器, 原样返回参数 echostr;
二. 开发校验程序
1. 要点解析
(1) 在servlet中获取四个参数
获取方法 : 在doGet()方法中, 直接调用request的getParameter("signature")方法, 即可获取signature参数;
-- 示例 :
//获取微信服务器发送给我们的四个参数
String signature = req.getParameter("signature");
String timestamp = req.getParameter("timestamp");
String nonce = req.getParameter("nonce");
String echostr = req.getParameter("echostr");
(2) 将参数按照字典顺序排序
排序方法 : 数组工具类 Arrays.sort()会自动将数组中的字符串按照字典循序排序;
-- 代码示例 :
//将token timestamp nonce 按照字典顺序排序
String[] params = new String[]{token, timestamp, nonce};
Arrays.sort(params);
//将上面三个参数排序之后拼接成字符串
StringBuffer buffer = new StringBuffer();
for(int i = 0; i < params.length; i ++){
buffer.append(params[i]);
}
(3) sha1 加密
获取MessageDigest加密类 : 通过调用 MessageDigest.getInstance("SHA-1"), 即可获取sha1加密类;
-- 代码示例 :
//获取sha1加密对象
MessageDigest digest = MessageDigest.getInstance("SHA-1");
//将组合后的字符串使用sha1加密, 加密后获得一个byte数组
byte[] byteDigest = digest.digest(buffer.toString().getBytes());
(4) byte数组转为字符串
byte转为char类型 :
-- 示例代码 :
/*
* 将byte转为字符串
*/
public static String byte2HexStr(byte b) {
char[] digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
char[] temp = new char[2];
temp[0] = digit[(b >>> 4) & 0x0F];
temp[1] = digit[b & 0x0F];
String s = new String(temp);
return s;
}
byte数组转为字符串 : 需要调用上面的类;
-- 示例代码 :
/*
* 将byte数组转为字符串
*/
public static String byte2str(byte[] byteArray) {
String str = "";
for(int i = 0; i < byteArray.length; i ++){
str += byte2HexStr(byteArray[i]);
}
return str;
}
(5) 向微信服务器发送信息
发送信息 : 先获取输出流, 然后校验, 如果通过校验就向微信服务器发送信息;
-- 示例代码 :
//创建一个出处流, 用于向微信服务器发送数据
PrintWriter out = resp.getWriter();
//如果校验通过, 向微信服务器发送echostr参数
if(VerifyUtils.checkSignature(signature, timestamp, nonce)){
out.print(echostr);
}
//释放资源
out.close();
out = null;
.
2. 程序源码
GitHub源码位置 :
-- HTTP :https://github.com/han1202012/WeChatVerify.git
-- SSH :git@github.com:han1202012/WeChatVerify.git
CSDN下载认证程序的war包和源码 :http://download.csdn.net/detail/han1202012/6999207
微信验证war包下载 :
-- 访问地址 :ip地址:80/WeChatVerify/verifyServlet ;
-- Token : 注意Token是 "hanshuliang" ;
程序结构 :
Servlet源码 :
package shuliang.han.vertify.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import shuliang.han.vertify.VerifyUtils;
public class VerifyServlet extends HttpServlet {
private static final long serialVersionUID = 4440739483644L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//获取微信服务器发送给我们的四个参数
String signature = req.getParameter("signature");
String timestamp = req.getParameter("timestamp");
String nonce = req.getParameter("nonce");
String echostr = req.getParameter("echostr");
//创建一个出处流, 用于向微信服务器发送数据
PrintWriter out = resp.getWriter();
//如果校验通过, 向微信服务器发送echostr参数
if(VerifyUtils.checkSignature(signature, timestamp, nonce)){
out.print(echostr);
}
//释放资源
out.close();
out = null;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//注意这里不能有任何操作, 否则不能完成验证
}
}
验证工具类源码 :
package shuliang.han.vertify;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
public class VerifyUtils {
private final static String token = "hanshuliang";
public static boolean checkSignature(String signature, String timestamp, String nonce) {
//将token timestamp nonce 按照字典顺序排序
String[] params = new String[]{token, timestamp, nonce};
Arrays.sort(params);
//将上面三个参数排序之后拼接成字符串
StringBuffer buffer = new StringBuffer();
for(int i = 0; i < params.length; i ++){
buffer.append(params[i]);
}
//str用于存储加密后的字符串
String str = null;
try {
//获取sha1加密对象
MessageDigest digest = MessageDigest.getInstance("SHA-1");
//将组合后的字符串使用sha1加密, 加密后获得一个byte数组
byte[] byteDigest = digest.digest(buffer.toString().getBytes());
//获取加密后的字符串, 将byte数组转化为字符串
str = byte2str(byteDigest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
/*
* 将加密后的字符串 与 signature 参数进行比较,
* 如果加密后的字符串为null直接返回false
* 如果加密后的字符串不为null, 直接返回
*/
boolean isVerified = (str != null) ? str.equals(signature.toUpperCase()) : false;
return isVerified;
}
/*
* 将byte数组转为字符串
*/
public static String byte2str(byte[] byteArray) {
String str = "";
for(int i = 0; i < byteArray.length; i ++){
str += byte2HexStr(byteArray[i]);
}
return str;
}
/*
* 将byte转为字符串
*/
public static String byte2HexStr(byte b) {
char[] digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
char[] temp = new char[2];
temp[0] = digit[(b >>> 4) & 0x0F];
temp[1] = digit[b & 0x0F];
String s = new String(temp);
return s;
}
}
web.xml配置文件 :
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>verifyServlet</servlet-name>
<servlet-class>shuliang.han.vertify.servlet.VerifyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>verifyServlet</servlet-name>
<url-pattern>/verifyServlet</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
三. 进行校验
1.部署程序
(1) 导出war包
(2) 将war包上传到服务器
(3) 配置Tomcat的server.xml文件
微信服务器只能接受80端口数据 :
<Connector port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
2. 使用阿里云服务器
将上面的程序导出的war包, 放到阿里云Tomcat服务器下 : 使用 http://hanshuliang.com:8080/WeChatVerify/verifyServlet登陆;
-- 结果 : 这是正常情况, 因为在POST中没有添加参数;
HTTP Status 500 -
typeException report
message
descriptionThe server encountered an internal error () that prevented it from fulfilling this request.
exception
java.lang.NullPointerException
java.lang.String.compareTo(String.java:1168)
java.lang.String.compareTo(String.java:92)
java.util.Arrays.mergeSort(Arrays.java:1144)
java.util.Arrays.sort(Arrays.java:1079)
shuliang.han.vertify.VerifyUtils.checkSignature(VerifyUtils.java:13)
shuliang.han.vertify.servlet.VerifyServlet.doGet(VerifyServlet.java:28)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
noteThe full stack trace of the root cause is available in the Apache Tomcat/6.0.20 logs.
Apache Tomcat/6.0.20
不支持8080端口, 只支持80端口, 我的服务器上跑着ngix服务器, 独立域名博客在上面那 : 郁闷 ...
2. 开始校验
原来的Ngix服务器中80端口是独立域名博客, 现在讲独立域名博客指到 8086端口中 : 现在独立域名博客可以从http://hanshuliang.com:8086/访问;
将Tomcat设置成80端口, 气死我了 ;
终于成功了 : 哭死了, 调试了好长时间啊, 终于通过了;
接口功能不全, 只有基础接口的权限 ...
GitHub源码位置:
--HTTP:https://github.com/han1202012/WeChatVerify.git
--SSH:git@github.com:han1202012/WeChatVerify.git
CSDN下载认证程序的war包和源码:http://download.csdn.net/detail/han1202012/6999207
微信验证war包下载:
--访问地址:ip地址:80/WeChatVerify/verifyServlet ;
--Token: 注意Token是 "hanshuliang" ;
.
作者:万境绝尘
转载请注明出处:http://blog.csdn.net/shulianghan/article/details/20494177
.
分享到:
相关推荐
其实微信开发文档说的确实十分详细了,而且使用官方给的demo,只要做稍稍的改变就可以直接用了。但是为什么总是提示错误呢? 下面我先贴出我验证成功的回调模式开启的代码 <?php //回调开启 include_once ...
微信公众号=开发者模式的启用,最简配置程序。在应用中只需把程序中的token值复制到你在公众平台-开发者模式下的token中。并根据文中的servlet地址,发布到公有网络中,配置服务器url。基本就行了。有疑惑可以发送...
开启开发模式 消息交互详解 自定义菜单 授权获取用户信息 一键导出微信所有用户信息到Excel 如何使用JSSDK 微信买单 微信公众号支付 微信扫码支付 微信刷卡支付 微信模板消息 微信红包 会员注册、找回...
NULL 博文链接:https://coderdream.iteye.com/blog/2145907
刘运强,网名“柳峰”,资深微信公众平台应用开发工程师,国内微信公众平台应用开发的先驱之一,项目经验丰富。他还是一位资深的Java软件开发工程师和Android/iOS移动应用开发工程师,活跃于CocoaChina、开源中国、...
所以我们启用微信公众号的开发模式之后,那些菜单是看不到的哦。不过现在个人订阅号是不可以使用高级开发者模式的,如自定义菜单,不过我们还是可以通过测试号来测试一下,然后移代码到服务号。 自定义类型包括...
云开发全球手机验证码发放+短视频去水印等组合微信小程序源码 带流量主 这是一款特别的小程序,验证码功能可能大家都还没见过吧! 支持全球验证码发放,支持激励视频查看更多手机号码 另外还有短视频平台去水印解析...
微信企业号开发的准备工作,开启回调模式的URL验证以及接受微信企业用户的消息,包括文本、图片、图文、语音和视频消息
主要为大家详细介绍了java微信企业号开发之开发模式的开启方法,感兴趣的小伙伴们可以参考一下
随着移动互联网技术的发展和用户需求的变化,【小程序名称】应运而生,以其轻量化、便捷化的设计理念为用户提供了一种全新的服务模式。作为一款无需下载安装即可使用的应用,【小程序名称】依托于微信庞大的生态系统...
公众号场景:用户在微信内进入商家公众号,打开某个页面,选择某个产品,完成支付。 PC网站场景:在网站中展示二维码,用户使用微信扫描二维码,输入需要支付的金额,完成支 付。 特点:用户在客户端输入支付金额 ...
微信公众平台接口开发指南 ... ... 注意:设置公众号信息时一定要谨慎,‘公众号名称’与‘微信号’填写后是不能修改的,需事先认真想好 ...其中有两个模式:‘编辑模式’与‘开发模式’ 默认开启的为‘编辑模式’
微信支付服务商jsapi支付demo.zip
在回调模式下,企业不仅可以主动调用企业号接口,还可以接收用户的消息或事件。当你开启应用的回调模式时,企业号会要求你填写应用的URL、Token、EncodingAESKey三个参数。 此源码为自用已验证源码。供参考。
微信开发系列的入门,包括模式启用和各类的消息回复,让大家对微信开发有基本的理解,也为大家进行其他微信公众号接口开发打开大门
DotNet开发的微商分销系统源码,微信三级分销系统源码 开发环境:vs2017 +sql server 2012 部署环境:iis7,.netframework 4.0,应用程序池为4.0经典模式。 安装请注意: 1、将安装目录:UI.Web拷贝到服务器上,搭建...
不需要将"use strict"放在脚本文件的第一行,微信小程序开发工具开启ES6转换功能的情况下,默认启用javasctipt严格模式(Strict Mode)。 用块级作用域代替IIFES IIFE(立即执行函数表达式)的通常用途是创造一个...
改源码采用的微信原生云开发模式 无需服务器和域名,也无需设置合法域名 只是需要简单的设置一下云函数和创建数据库即可 相信大家最近耶看到过或者听说过这类型商品吧 比如各大城市摆地摊的还有各大短视频平台...
随着移动互联网技术的发展和用户需求的变化,【小程序名称】应运而生,以其轻量化、便捷化的设计理念为用户提供了一种全新的服务模式。作为一款无需下载安装即可使用的应用,【小程序名称】依托于微信庞大的生态系统...