微信测试号接入微信【验证token】

微信测试号接入微信,并验证token

基于java语言的微信测试号接入。

1) 申请微信测试号

【链接】微信公众平台接口测试帐号申请
https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

直接扫码登录
在这里插入图片描述

2)本地代码编写

当前使用的代码示例,使用servlet来编写的,用于接收微信服务器发送的请求,验证相关参数,确定发送者为微信端。

package web;

import service.WeChatCheck;

import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @Description
 * @Author zc
 * @Date 2020/7/28 下午4:23
 */
@WebServlet("/wx")
public class WeChat extends HttpServlet {

    /**
     * 校验微信请求
     * */
    @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");

        //校验请求是否来自微信
        boolean check = WeChatCheck.check(signature, timestamp, nonce);
        //如果来自微信,将echostr原样返回,表示接入微信成功
        if (check){
            PrintWriter writer = resp.getWriter();
            writer.write(echostr);
            writer.flush();
            if (writer!=null){
                writer.close();
            }
        }
    }

    /**
     * 校验成功后,公众号接收到的消息会以POST请求发送到当前路由
     * */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletInputStream inputStream = req.getInputStream();

        //使用字节流读取公众号接收到的消息
        byte[] bytes = new byte[1024];
        int len = 0;
        StringBuffer sb  = new StringBuffer();
        while ((len = inputStream.read(bytes)) != -1){
            sb.append(new String(bytes,0,len));
        }
        System.out.println(sb.toString());

    }
}

微信请求数据验证

package service;

import jdk.nashorn.internal.runtime.FindProperty;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

/**
 * @Description
 * @Author zc
 * @Date 2020/7/28 下午5:09
 */
public class WeChatCheck {

    //token字段与微信开发页面填写的token保持一致
    private static final String TOKEN = "abac";

    /**
     * 校验微信微信接入是否成功
     * signature:微信服务器{token,timestamp,nonce}经过sha1加密后的字段(微信签名)
     *
     * 本地使用token加微信服务器发送过来的timestamp,nonce进行字段排序后,经过sha1加密(本地签名)
     *
     * 如果 微信签名 == 本地签名
     *      表示微信服务器中的token,与本地的token是同一个token
     *      微信接入成功
     * */
    public static boolean check(String signature,String timestamp,String nonce){

        String[] strings = new String[]{TOKEN,timestamp,nonce};
        System.out.println("排序前");
        for (String str : strings){
            System.out.println(str);
        }

        //字典排序
        Arrays.sort(strings);
        System.out.println("排序后");
        for (String str : strings){
            System.out.println(str);
        }

        //将strings进行sha1加密后与signature比较
        String encrypt = encrypt(strings);

        System.out.println("微信签名"+signature);
        System.out.println("加密签名"+encrypt);

        return encrypt.equals(signature);
    }


    /***
     * 将{TOKEN,timestamp,nonce}字符数组按字典排序,合并成一个字符串
     * 获取合并后字符串,获取其字节流(byte)
     * 获取sha1加密对象,将字节流数组加密
     *
     * 加密后的字节流进行简单处理,将其转换为16进制的字符串
     *          每一个byte按照4bit拆分,然后转换为16进制字符串
     *
     */
    private static String encrypt(String[] strings){
        StringBuffer str = new StringBuffer();
        for (String s : strings){
            str.append(s);
        }

        try {
            //获取sha1加密对象
            MessageDigest md = MessageDigest.getInstance("sha1");
            //获取字符串的byte数组,并加密
            byte[] digest = md.digest(str.toString().getBytes());
            //声明0~f的字符数组
            char[] chars = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
            //返回结果字符串拼接
            StringBuffer sb = new StringBuffer();
            //循环加密后的byte数组,转换为16进制的字符数组
            for (byte b : digest){
                sb.append(chars[(b>>4)&15]);
                sb.append(chars[(b&15)]);
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }
}

在编写好代码,运行起来,在确保能够通过域名访问后,填写URL和token。点击提交后,微信会发送请求到填写的URL,携带四个参数。

参数描述作用
signaturesignature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。token+timestamp+nonce进行字典排序后,再使用sha1加密后生成的字符串
timestamp时间戳当前demo不关心
nonce随机数当前demo不关心
echostr随机字符串进行验证后,返回给微信端的数据

如果能够成功接收到微信发送的GET请求,并完成Token验证后,返回相应的结果,页面会提示配置成功。
在这里插入图片描述
URL:在填写URL前,需要保证URL能够访问到,也就是说,这里的URL是一个能够在网络上访问到的地址,可以使用域名+云服务器,也可以使用内网穿透。

Token:token值的填写没有规则限制,但是在本地代码中需要使用到,用于验证微信连接。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值