zoukankan      html  css  js  c++  java
  • 微信开发之启用开发者模式(三)

    一、准备环境

      1、JDK1.6及以上版本

      2、Eclipse

      3、Tomcat

      4、Ngrok

    二、步骤

      1、访问微信公众平台开发者手册  https://mp.weixin.qq.com/wiki  如下是接入规则(来自开发者手册):

         开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,GET请求携带参数如下表所示:

    参数 描述
    signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
    timestamp 时间戳
    nonce 随机数
    echostr 随机字符串

        

    开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。加密/校验流程如下:

    1)将token、timestamp、nonce三个参数进行字典序排序

    2)将三个参数字符串拼接成一个字符串进行sha1加密

    3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信

      2、接入微信开发者模式开始

        我们细细品味微信提供的规则:若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败

        我们索性就在get方法中获取echostr直接返回,按照此规则,我先来创建一个web项目,并创建一个Servlet,代码如下:

        

    package com.weixin.util;
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * Servlet implementation class SignUtil
     */
    @WebServlet("/SignUtil")
    public class SignUtil extends HttpServlet {
    	private static final long serialVersionUID = 1L;
    
        /**
         * Default constructor. 
         */
        public SignUtil() {
            // TODO Auto-generated constructor stub
        }
    
    	/**
    	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
    	 */
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		String echostr=request.getParameter("echostr");
    		response.getWriter().print(echostr);
    	}
    
    	/**
    	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
    	 */
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		// TODO Auto-generated method stub
    	}
    
    }
    

        将项目不部署到Tomcat,可以正常访问Servlet,返回null。OK

      3、开启Ngrok,用Ngrok映射的域名也可以正常访问Servlet,若不懂Ngrok的设置,请参考我的博文 微信开发第一篇

      4、登录到微信公众平台,在开发--》基本配置,首次开启,会让你确认,勾选“我同意”,成为开发者 如下图:

        

      5、在基本配置中,点击修改配置,修改配置

         URL:对应我们Servlet地址,注意:这里要是我们ngrok映射的域名

         Token:可随意的英文组合

         EncodingAESKey:随机生成

        消息加密方式:明文模式

        

           点击【修改配置】

        

      6、提交后点击【启用】,就可以启用我们的开发者模式了

        

        

      7、虽然我们投机取巧,成功的启用开发者模式,但是这种方式是不符合微信的规则,

         下面我们通过微信的方式,来实现启用开发者模式:

        1)将token、timestamp、nonce三个参数进行字典序排序

        2)将三个参数字符串拼接成一个字符串进行sha1加密

        3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信

        直接上代码:

        

    package com.weixin.util;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import java.util.Arrays;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * Servlet implementation class SignUtil
     */
    @WebServlet("/SignUtil")
    public class SignUtil extends HttpServlet {
    	private static final long serialVersionUID = 1L;
        private static String token = "weixin";
        /**
         * Default constructor. 
         */
        public SignUtil() {
            // TODO Auto-generated constructor stub
        }
    
    	/**
    	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
    	 */
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		
    				//微信服务器get传递的参数
    				String signature = request.getParameter("signature");
    				String timestamp = request.getParameter("timestamp");
    				String nonce = request.getParameter("nonce");
    				String echostr = request.getParameter("echostr");
    				
    				PrintWriter out = response.getWriter();
    				if (this.checkSignature(signature, timestamp, nonce)) {
    					out.print(echostr);
    				}
    				
    				out.close();
    				out = null;
    	}
    
    	/**
    	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
    	 */
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		// TODO Auto-generated method stub
    	}
    	    /**
    	     *
    	     * @param signature
    	     * @param timestamp
    	     * @param nonce
    	     * @return
    	     */
    	    public static boolean checkSignature(String signature, String timestamp, String nonce){
    	        String[] arr = new String[]{token, timestamp, nonce};
    	        //排序
    	        Arrays.sort(arr);
    	        
    	        StringBuilder content = new StringBuilder();
    	        for(int i = 0; i < arr.length; i++){
    	            content.append(arr[i]);
    	        }
    	        MessageDigest md = null;
    	        String tmpStr = null;
    	         
    	        try {
    	            md = MessageDigest.getInstance("SHA-1");
    	            //SHA-1加密
    	            byte[] digest = md.digest(content.toString().getBytes());
    	            tmpStr = byteToStr(digest);
    	        } catch (NoSuchAlgorithmException e) {
    	            // TODO Auto-generated catch block
    	            e.printStackTrace();
    	        }
    	        content = null;
    	        // 比对 判断
    	        return tmpStr != null ? tmpStr.equals(signature.toUpperCase()): false;
    	    }
    	     
    	   /**
    	    * 
    	    * @param digest
    	    * @return
    	    */
    	    private static String byteToStr(byte[] digest) {
    	        // TODO Auto-generated method stub
    	        String strDigest = "";
    	        for(int i = 0; i < digest.length; i++){
    	            strDigest += byteToHexStr(digest[i]);
    	        }
    	        return strDigest;
    	    }
    	    
    	    /**
    	     * 
    	     * @param b
    	     * @return
    	     */
    	    private static String byteToHexStr(byte b) {
    	    	
    	        char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
    	        char[] tempArr = new char[2];
    	        tempArr[0] = Digit[(b >>> 4) & 0X0F];
    	        tempArr[1] = Digit[b & 0X0F];
    	         
    	        String s = new String(tempArr);
    	        return s;
    	    }
    	
    
    }
    

      

        8、重新启用自己的开发者模式,看是否能成功,若验证不通过,欢迎各位在评论区提问,谢谢各位

       所有博文内容,全部是自己一步一步操作出来的,请尊重版权,若转载请说明出处,谢谢。

        


    所有博文内容,全部是自己一步一步操作出来的,请尊重版权,若转载请说明出处,谢谢。
    不为失败找借口,只为成功找方法。欢迎各位和我一起遨游code世界!!!
  • 相关阅读:
    Optimal Logging
    表单设计平台主要功能截图介绍
    表单设计器在线测试地址
    React-Native 之控件布局
    Week,Month, Year 日期区间辅助类
    WPF 文本框添加水印效果
    WPF 自定义窗口
    正则表达式总结
    基于Extjs的web表单设计器 第七节——取数公式设计之取数公式的使用
    基于Extjs的web表单设计器 第七节——取数公式设计之取数公式定义
  • 原文地址:https://www.cnblogs.com/codejackanapes/p/5469861.html
Copyright © 2011-2022 走看看