微信公众号开发-----验证接入

  1. 首先要先申请一个测试账号(用于开发测试及功能体验),这种是平常普通用户是涉及不到的,是专门为开发人员准备的一种仅用于测试的公众号。由于用户体验和安全性方面的考虑,微信公众号的注册有一定门槛,某些高级接口的权限需要微信认证后才可以获取。所以,为了帮助开发者快速了解和上手微信公众号开发,熟悉各个接口的调用,微信推出了公众帐号测试号,无需公众帐号、快速申请接口测试号,通过手机微信扫描二维码即可获得,利用测试号我们可以体验和测试更多高级功能。
    测试账号申请地址:
    http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
    但测试号也不是万能的,部分高级功能,如微信支付,卡券功能等也是不开放的。
    如果要实现支付功能还是得去注册个正式的公众号。

  2. 登录测试号页面,可以看到该测试号相关的信息。
    就是使用电脑打开 http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
    使用微信扫一扫二维码,即可在打开的页面中看见微信给你分配的测试号的相关信息。
    下面两个属性是唯一的标识,每个测试号都会有自己的appid与appsecret ,是比较重要的信息,不要随意发给别人:
    appid:是公众号开发识别码,配合开发者密码可调用公众号的接口能力。
    appsecret:是校验公众号开发者身份的密码,具有极高的安全性。

    在这里插入图片描述
    如果是正式的公众号,登录公众平台官网之后,找到“基本配置”菜单栏也可以获取上公众号相关的信息。
    再往下看,我们会看到URL和Token这两个属性,和上面appid/appsecret不同的是,上面的是微信分配给我们的,但是下面这两个是需要我们填进去的。
    URL:就是指我们自己的服务器地址
    该URL是开发者用来接收和响应微信消息和事件的接口URL(必须以http://或https://开头,分别支持80端口和443端口)
    Token:可任意填写,用作生成签名(必须为英文或数字,长度为3-32字符)
    该签名在后边会用到,这里暂时随便填个内容也可以
    在这里插入图片描述

  3. 接下来我们需要了解的是微信与我们的服务器交互的过程:
    当我们在微信app上,给公众号发送一条内容的时候,实际会发送到微信的服务器上,此时微信的服务器就会对内容进行封装成某种格式的数据比如xml格式,再转发到我们配置好的URL上,所以该URL实际就是我们处理数据的一个请求路径。所以该URL必须是能暴露给外界访问的一个公网地址,不能使用内网地址,生产环境可以申请腾讯云,阿里云服务器等,但是在开发环境中可以暂时利用一些软件来完成内网穿透,便于修改和测试,如NATAPP,花生壳等软件,使用起来也很方便,在本地安装对应的软件,配置运行后,直接使用软件分配的临时域名来访问本地应用即可,只是偶尔会存在网络不稳定的情况。这里不详细介绍如何使用了,具体教程可参考软件官网。
    在这里插入图片描述

  4. 在开发的过程中,我们会经常使用到微信公众号提供给开发者的开发文档:
    具体地址:https://mp.weixin.qq.com/wiki
    大家打开后可以选择”接入指南”,参考微信提供的一些帮助信息。

  5. URL接入验证:
    我们需要先来了解一下接入的过程是怎么样的。下图是微信官方对接入过程的介绍。
    在这里插入图片描述
    由以上介绍可知,当我们填入url与token的值,并提交后,微信会发送一个get请求到我们填写的url上,并且携带4个参数,而signature参数结合了开发者填写的token参数和请求中的timestamp参数、nonce参数来做的加密签名,我们在后台需要对该签名进行校验,看是否合法。实际上,我们发现微信带过来的4个参数中并没有带token参数,仅有signature是和token有关的,所以我们应该在本地应用中也准备一个和填入的token相同的参数,再通过微信传入的timestamp与nonce做相同算法的加密操作,若结果与微信传入的signature相同,即为合法,则原样返回echostr参数,代表接入成功,否则不做处理,则接入失败。

  6. 代码示例:

@Controller
@RequestMapping("/check")
public class JieruController {

    private static final String token = "开发者在页面上自行定义的Tooken"; //开发者自行定义的Tooken

    /**
     * 验证接口
     * By Oliver_Deng
     * @param request
     * @param response
     * @throws IOException
     */
    @GetMapping("/signature")
    public void get(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //消息来源可靠性验证
        String signature = request.getParameter("signature");// 微信加密签名
        String timestamp = request.getParameter("timestamp");// 时间戳
        String nonce = request.getParameter("nonce");       // 随机数
        //Token为weixin4j.properties中配置的Token
//        String token = TokenUtil.get();

        //1.验证消息真实性
        //http://mp.weixin.qq.com/wiki/index.php?title=验证消息真实性
        //成为开发者验证
        String echostr = request.getParameter("echostr");
        //确认此次GET请求来自微信服务器,原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败
        if (TokenUtil.checkSignature(token, signature, timestamp, nonce)) {
            response.getWriter().write(echostr);
        }

    }

上述代码中用到的TokenUtil:

/*
 * 微信公众平台(JAVA) SDK
 *
 * Copyright (c) 2014, Ansitech Network Technology Co.,Ltd All rights reserved.
 * 
 * http://www.weixin4j.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.weixin4j.util;

import org.weixin4j.Configuration;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * <p>
 * Title: 微信公众平台Token算法工具类</p>
 *
 * <p>
 * Description: 为应用提供URL算法 根据不同的URL返回不同的Token,以适应多微站的需求
 * 例如:Url:http://www.weixin4j.org/api/tiexinqiao
 * 则默认Token:为jEvQdLxi0PvtgK8N+HzUpA== 根据配置的系统Token不同,而改变</p>
 *
 * @author yangqisheng
 * @since 0.0.1
 */
public class TokenUtil {

    //此加密密钥用于加密公众号Token,一经配置,不能修改,一旦修改,所有公众号需要重新填写Token
    private static String systemToken = null;

    /**
     * 获取配置文件配置的Token
     *
     * @return 微站Token
     */
    public static String get() {
        if (systemToken == null) {
            systemToken = Configuration.getProperty("weixin4j.token", "weixin4j");
        }
        return systemToken;
    }

    /**
     * 加密/校验流程如下:
     *
     * <p>
     * 1. 将token、timestamp、nonce三个参数进行字典序排序<br>
     * 2.将三个参数字符串拼接成一个字符串进行sha1加密<br>
     * 3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信<br>
     * </p>
     *
     * @param token Token验证密钥
     * @param signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数,nonce参数
     * @param timestamp 时间戳
     * @param nonce 随机数
     * @return 验证成功返回true,否则返回false
     */
    public static boolean checkSignature(String token, String signature, String timestamp, String nonce) {
        List<String> params = new ArrayList<String>();
        params.add(token);
        params.add(timestamp);
        params.add(nonce);
        //1. 将token、timestamp、nonce三个参数进行字典序排序
        Collections.sort(params, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });
        //2. 将三个参数字符串拼接成一个字符串进行sha1加密
        String temp = SHA1.encode(params.get(0) + params.get(1) + params.get(2));
        //3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
        return temp.equals(signature);
    }
}
  1. 完成

遇到的坑:
我们都是用自己内网的ip地址,而微信验证的URL需要用到能够访问的外网地址,所以我们需要做内网穿透,映射外网出来。

一开始我是用ngrok来做映射,这个需要去官网注册账号,然后获得开启码,再进行映射(具体自行百度),然而我就卡在注册账号的问题上,一直都注册不上。后来就改用了花生壳。

在这里插入图片描述
花生壳使用教程:
http://service.oray.com/question/2480.html

注意:
在这里插入图片描述
在你花生壳的账户是离线状态的时候,是可以给你添加到外网地址的。
但是需要登录后才能看到外网访问地址。这种操作实在不理解。

部分内容参考自:
https://blog.csdn.net/wolfcode_cn/article/details/80773198

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值