微信公众号验证Token

前几天开发了微信公众号,趁今天有时间,总结一下。

注意几点:

1.服务器地址URL这是要配置你的域名加你验证Token的接口路径,记住,是完整路径!。如果是通过了穿透,那么就是127.0.0.1/端口/Controller路径/方法路径!

2.令牌Token问题,在微信公众号基本配置里面可以随意填写,但是在服务端,也就是你的后台接口程序中的Token必须对应!

3.消息加解密密钥,这个在公众号可以弄成自动生成32的密钥。

4.加解密方式,本人用的是明文。

5.Token每天获取数量有限制,每次获取有效期是7200,也就是2小时,记得用容器保存。可以存储在Redis,设置一个有效期7200!

以下是代码:

1.工具类Httprequests

public static String  sendGet (String url,String param) {
        String result ="";
        BufferedReader in  =null;
        try {
            String urlNameString = url +"?" +param;
            System.out.println("发送的链接请求:"+urlNameString);
            URL reaurl = new URL(urlNameString);

            URLConnection connection  = reaurl.openConnection();

            //设置通用
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "keep-Alive");
            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");

            //建立实际的连接
            connection.connect();

            Map<String, List<String>> map = connection.getHeaderFields();
            //定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送GET请求出现异常!" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result;
    }


    /**
     * 向指定 URL 发送POST方法的请求
     * @param url 发送请求的 URL
     * @param param 参数
     * @return String 所代表远程资源的响应结果
     */
    public static String sendPost(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());

            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常!"+e);
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally{
            try{
                if(out!=null){
                    out.close();
                }
                if(in!=null){
                    in.close();
                }
            }
            catch(IOException ex){
                ex.printStackTrace();
            }
        }
        return result;
    }


    /**
     * 拿到ip
     * @param req request作用域:
     * @return String
     */
    public static String getRemoteIP(HttpServletRequest req) {
        String ip = req.getHeader("X-Real-IP");

        if (ip == null || ("").equals(ip)) {
            ip = req.getRemoteAddr() == null ? "127.0.0.1" : req.getRemoteAddr();
        }
        return ip;
    }

    /**
     *  生成
     * @param num 参数
     * @return String
     */
    public static String getPamens(Integer num){
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < num; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

2.写一个Service接口,返回Map类型。

 /**
     * 获取微信Token
     * @return
     */
     Map<String, Object> accessToken();

3.实现接口 lmpl

  /**
     * 拿到Token
     * @return
     */
    @Override
    public Map<String, Object> accessToken() {
        String param="grant_type="+ WxModel.grant_type+"&appid="+WxModel.appid+"&secret="+WxModel.wxspSecret;
        //获取接口凭证
        String sendGet= Httprequests.sendGet(WxModel.select_access_token,param);
        System.out.println("发送git请求的返回值:"+sendGet);
        JSONObject json = JSONObject.parseObject(sendGet);
        String access_token=json.getString("access_token"); //凭证
        System.out.println("获取的access_token:"+access_token);
        int expires_in= json.getInteger("expires_in"); //凭证有效时间,单位:秒
        System.out.println("有效的时间:"+expires_in);
        System.out.print("获取凭证成功");
        System.out.println("返回的数据:"+access_token);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("access_token", access_token);
        map.put("expires_in", expires_in);
        RedisUtil.setex("access_token",access_token,7200 );
        return map;
    }

4.关于WxModel,这个是要你公众号的grant_type,appid,wxspSecret,你可以登录你的公众号进行查看。在首页就可以看到

5 .Controller,如果运行报请求要用GET请求,那么就把POST换成GET。

/**
     * 验证token
     * @param request
     * @param response
     * @return
     */
    @PostMapping(value= {"/getProcessRequest"})
    @ResponseBody
    public String getProcessRequest(HttpServletRequest request, HttpServletResponse response) {
        boolean isGet=request.getMethod().toLowerCase().equals("get");
        System.out.println(isGet);
        System.out.println("方法是-------"+isGet);
         // 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
            String signature = request.getParameter("signature");
            // 时间戳
            String timestamp = request.getParameter("timestamp");
            // 随机数
            String nonce = request.getParameter("nonce");
            // 随机字符串
            String echostr = request.getParameter("echostr");

            PrintWriter out = null;
            try {
                out = response.getWriter();
                // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,否则接入失败
                if (SignUtil.checkSignature(signature, timestamp, nonce)) {
                    System.out.println("成功");
                    out.print(echostr);
                    out.flush();  //必须刷新
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                out.close();
            }
    }

总结完毕,在此要感谢我一个同学,他开发过这方面,让我少爬了很多坑。代码是完整的,希望可以帮助到大家。

不懂可以加QQ群: 914084240

发布了72 篇原创文章 · 获赞 16 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_40206199/article/details/103233571