微信开发之启用开发者模式(三)

一、准备环境

  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世界!!!
原文地址:https://www.cnblogs.com/codejackanapes/p/5469861.html