java开发微信服务号(四) 验证消息的确来自微信服务器

为了在公众号里配置下图时使用的代码:

Controller层代码:

import com.weixin.wxDemo.service.CheckTokenService;
import lombok.extern.log4j.Log4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Log4j
@Controller
@RequestMapping("/checkTokenUtil")
public class CheckTokenController {

    @Autowired
    private CheckTokenService checkTokenService;

    /**
     * 验证消息是否来自微信服务器
     * signature:微信加密签名
     * timestamp:时间戳
     * nonce:随机数
     * echostr:随机字符串
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "checkToken", method = RequestMethod.GET)
    public void checkToken(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");
        //验证
        String newStr = checkTokenService.checkToken(signature, timestamp, nonce, echostr);
        if (!echostr.equals(newStr)) {
            log.error("消息不是来自微信服务器!");
        } else {
            response.getOutputStream().println(echostr);
        }

    }
}

Service层代码:

import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.Arrays;

/**
 * @Auther: 抹茶冰冰冰
 * @Date: 2020-04-02
 * @Description: 验证消息是否来自微信服务器
 **/
@Service
@RequestMapping("checkTokenService")
public class CheckTokenService {
    /**
     * 这里获取的是配置文件里的token的值
     */
    @Value("${weixin.token}")
    private String token;

    /*
     *  获取accessToken的服务接口
     */
    @Autowired
    private GetAccessTokenService getAccessTokenService;

    public String checkToken(
            String signature,
            String timestamp,
            String nonce,
            String echostr) {
       //调用所有接口前都需要获取accessToken
        String accessToken = getAccessTokenService.getAccessToken();
        if(StringUtils.isBlank(accessToken)){
            return "";
        }
       //放入数组,进行字典排序后组成一个字符串。
        String[] arr = new String[]{token, timestamp, nonce};
        Arrays.sort(arr);
        String str = arr[0] + arr[1] + arr[2];
       //sha1加密,这里可以手写也可以用jar包,我选择用jar包,具体的maven依赖在该系列文章的第一章里。
       //如果选择手写,可以参考第三段的代码段。
        String resultMsg = DigestUtils.sha1Hex(str);
        if (!resultMsg.equals(signature)) {
            return "";
        }
        return echostr;

    }
}

上一段代码中的sha1加密我使用的是工具包,如果大家需要手写,可以将“ String resultMsg = DigestUtils.sha1Hex(str);”这段代码

修改成如下代码(这段代码不是我写的,具体出处也是各路大神。注意:手写这段代码里的英文都是大写的,在判断相等时要把equals()方法改成equalsIgnoreCase()方法或者将resultMsg转换成小写的也可以):

MessageDigest md = null;
        String resultMsg = null;
        try {
            md = MessageDigest.getInstance("SHA-1");
            byte[] digest = md.digest(str.getBytes());
            resultMsg = byteToStr(digest);

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

再在Service里加入如下两个方法:

 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();
    }
    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;
    }

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值