• 微信开发 之 开启开发模式


    .

    作者 : 万境绝尘

    转载请注明出处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 -


    type Exception report

    message

    description The 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)
    

    note The 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

    .


  • 相关阅读:
    (剑指Offer)面试题18:树的子结构
    (剑指Offer)面试题17:合并两个排序的链表
    (剑指Offer)面试题16:反转链表
    程序员水平分级 你属于哪一类?
    Hacker
    十分钟让你看懂中国经济形势,10分钟,坚持看完,必有所获~(转载)
    人口问题,怎样的生育率才能保持正常的世代更替?
    理科和文科的区别?
    柴晓霞:做销售要学会画蓝图 (转载)
    工作,为钱还是为理想
  • 原文地址:https://www.cnblogs.com/hanshuliang/p/4215430.html
Copyright © 2020-2023  润新知