1. 接入微信公众平台

首先去申请个测试账号,测试号传送门
使用微信授权登录后需要配置URL和Token,Token自己随便配置,URL必须使用公网可访问的域名,我们使用ngrok做一个反向代理生成一个公网的URL入口,ngrok传送门

2. 处理微信请求

上面环境搭好以后,此时点提交是配置不通过的,因为我们还没有对微信的请求做处理,这里的请求分为get和post两种请求

  • get:身份验证
  • post:处理消息
@RestController
@RequestMapping("/")
public class WechatController {

    @Autowired
    private WechatService wechatService;

    @RequestMapping("wechat")
    public void wechat(HttpServletRequest request, HttpServletResponse response, WechatVerifyBean wechatVerifyBean){
        Boolean isGet = "get".equalsIgnoreCase(request.getMethod());
        if (isGet){
            System.out.println("进入get方法");
            //get方法验证url有效性
            wechatService.checkSignature(request,response,wechatVerifyBean);
        }else{
            System.out.println("进入post方法");
            wechatService.acceptMessage(request,response);
        }
    }
}

3. get请求验证身份

这里主要是根据token,时间戳和随机数校验signature

@Component
public class WechatServiceImpl implements WechatService {

    @Value("${token}")
    private String token;

    @Override
    public String checkSignature(HttpServletRequest request, HttpServletResponse response, WechatVerifyBean wechatVerifyBean) {
        String echostr = wechatVerifyBean.getEchostr();
        String nonce = wechatVerifyBean.getNonce();
        String signature = wechatVerifyBean.getSignature();
        String timestamp = wechatVerifyBean.getTimestamp();

        List<String> accessList = new ArrayList<String>();
        accessList.add(nonce);
        accessList.add(timestamp);
        accessList.add(token);
        // 1)将token、timestamp、nonce三个参数进行字典序排序
        Collections.sort(accessList);
        // 2)将三个参数字符串拼接成一个字符串进行sha1加密
        String temp = SHA1.encode(accessList.get(0) + accessList.get(1) + accessList.get(2));
        // 3)获得加密后的字符串可与signature对比,标识该请求来源于微信
        if (temp.equals(signature)) {
            System.out.println("验证成功:echostr=" + echostr);
            try {
                response.getWriter().write(echostr);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return echostr;
        }
        return null;
    }

    @Override
    public void acceptMessage(HttpServletRequest request, HttpServletResponse response) {

    }
}