欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

手把手教你使用java对接微信公众号-签名验证

程序员文章站 2024-01-08 13:09:40
...

1、进入微信公众号登录界面,先用自己的微信去注册服务号。

登录地址:https://mp.weixin.qq.com 。登录成功进入找到“开发”一栏,选择“基本配置”,填写服务器配置。

手把手教你使用java对接微信公众号-签名验证

我们在测试的时候可以通过申请测试号进行开发,开发完成后再切换到正式环境。

2、登录微信官方文档 https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html,选择“接口测试号申请”,然后登陆即可。

手把手教你使用java对接微信公众号-签名验证

登录成功后是这个页面,但是接口配置信息应该是没有的,因为我已经配置了。

手把手教你使用java对接微信公众号-签名验证

接着点击添加“接口配置信息”,通过点击“消息接口使用指南”,可以看到这里的url填写规则必须是80或443端口。接下来我们来编写接口来校验签名,签名校验规则文档中也说了。

手把手教你使用java对接微信公众号-签名验证

3、编写签名验证接口

1)编写WxCheckSignatureController。

package com.example.mybaties.controller;

import com.example.mybaties.service.WxCheckSignatureService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Description:
 * @Author: lst
 * @Date 2020-08-18
 */
@RestController
@Api(value = "WxCheckSignatureController", tags = "验证消息的确来自微信服务器")
public class WxCheckSignatureController {

    @Autowired
    private WxCheckSignatureService wxCheckSignatureService;

    /**
     * @Description  验证消息的确来自微信服务器,签名验证
     * @author lst
     * @date 2020-8-18 12:03
     * @param signature 微信加密签名
     * @param timestamp 时间戳
     * @param nonce 随机数
     * @param echostr 随机字符串
     * @return java.lang.String
     */
    @GetMapping(value = "/check-token", produces = "application/json; charset=utf-8")
    @ApiOperation(value = "验证消息的确来自微信服务器,签名验证", notes = "验证消息的确来自微信服务器,签名验证", code = 200, produces = "application/json")
    @ApiImplicitParams({
       @ApiImplicitParam(paramType = "query", dataType = "string", name = "signature",required = true ,value = "微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。"),
       @ApiImplicitParam(paramType = "query", dataType = "string", name = "timestamp",required = true ,value = "时间戳"),
       @ApiImplicitParam(paramType = "query", dataType = "string", name = "nonce",required = true ,value = "随机数"),
       @ApiImplicitParam(paramType = "query", dataType = "string", name = "echostr",required = true ,value = "随机字符串")
    })
    public String checkToken(@RequestParam("signature") String signature, @RequestParam("timestamp") String timestamp,
                             @RequestParam("nonce") String nonce, @RequestParam("echostr") String echostr) {
        return  wxCheckSignatureService.checkSignature(signature, timestamp, nonce,echostr);
    }


}

2)、编写实现类WxCheckSignatureServiceImpl、WxCheckSignatureService、ShaUtil

package com.example.mybaties.service.impl;

import com.example.mybaties.service.WxCheckSignatureService;
import com.example.mybaties.utils.ShaUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;


/**
 * @Description: 
 * @Author: lst
 * @Date 2020-08-18
 */
@Slf4j
@Service
public class WxCheckSignatureServiceImpl implements WxCheckSignatureService {

    @Value("${wx.token}")
    public String token;

    /**
     * @Description  进行签名认证
     * @author lst
     * @date 2020-8-20 10:49
     * @param signature 微信加密签名
     * @param timestamp 时间戳
     * @param nonce 随机数
     * @param echostr 随机字符串
     * @return java.lang.String
     */
    @Override
    public String checkSignature(String signature, String timestamp, String nonce, String echostr) {
        // 1.将token、timestamp、nonce三个参数进行字典序排序
        log.info("signature:{},token:{},timestamp:{},nonce:{}",signature,token,timestamp,nonce);
        String tmpStr = ShaUtil.getSHA1(token,  timestamp,  nonce);
        //TODO 进行对比
        log.info("随机字符串echostr:{}",echostr);
        log.info("tmpStr:{}",tmpStr);
        if (tmpStr.equals(signature.toUpperCase())) {
            return echostr;
        }
        return null;
    }


}
package com.example.mybaties.service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @DESCRIPTION
 * @Author lst
 * @Date 2020-08-18
 */
public interface WxCheckSignatureService {

    String checkSignature( String signature, String timestamp,
                          String nonce,String echostr);

 
}
package com.example.mybaties.utils;

import lombok.extern.slf4j.Slf4j;

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

/**
 * @Description: 用SHA1算法验证Token
 * @Author: lst
 * @Date 2020-08-18
 */
@Slf4j
public class ShaUtil {

    /**
     * @Description  用SHA1算法验证Token
     * @author lst
     * @date 2020-8-20 11:30
     * @param token url相关的token
     * @param timestamp 时间戳
     * @param nonce 随机数
     * @return java.lang.String
     */
    public static String getSHA1(String token, String timestamp, String nonce){

        String[] arr = new String[] { token, timestamp, nonce };
        Arrays.sort(arr);
        //TODO 2. 将三个参数字符串拼接成一个字符串进行sha1加密
        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");
            // 将三个参数字符串拼接成一个字符串进行sha1加密
            byte[] digest = md.digest(content.toString().getBytes());
            tmpStr = byteToStr(digest);
        } catch (NoSuchAlgorithmException e) {
            log.info("错误信息:{}",e.getMessage());
        }

        return tmpStr;
    }

    /**
     * @Description 将字节数组转换为十六进制字符串
     * @author lst
     * @date 2020-8-18 11:56
     * @param byteArray
     * @return java.lang.String
     */
    private static String byteToStr(byte[] byteArray) {
        StringBuilder strDigest = new StringBuilder();
        for (int i = 0; i < byteArray.length; i++) {
            strDigest.append(byteToHexStr(byteArray[i]));
        }
        return strDigest.toString();
    }

    /**
     * @Description  将字节转换为十六进制字符串
     * @author lst
     * @date 2020-8-18 11:57
     * @param mByte
     * @return java.lang.String
     */
    private static String byteToHexStr(byte mByte) {
        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[(mByte >>> 4) & 0X0F];
        tempArr[1] = Digit[mByte & 0X0F];
        String s = new String(tempArr);
        return s;
    }

}

application.yml配置

wx:
  token: xxxxx

3)、代码完成后,我将服务搭建在了阿里云上,我这边使用的是IP还没有申请域名。将接口填写在URL上,token自己定义。点击提交后会提示成功

手把手教你使用java对接微信公众号-签名验证

在看看后台打印的日志

手把手教你使用java对接微信公众号-签名验证

 

 

 

 

相关标签: 微信 小程序