日常问题随笔 | 21.09.12

2021-10-08 15:41:43 浏览数 (1)

昨天在做公众号扫码登录的时候,公众号需要先验证web应用的token

在网上尝试了各种方案,总是有多多少少的问题,后来经过各种方案的结合,最终得到可以验证成功的版本:

环境:springboot

1、配置服务代理(这里我用的Nginx)

代码语言:javascript复制
server {
    location /{
        #注意,代理之后的端口必须是8080或443,否则验证失败
        proxy_pass http://你的ip:8080;
    }
}

2、controller

代码语言:javascript复制
@Controller
@RequestMapping("/oauth")
public class OAuthController {

    /**
     * 微信公众号签名认证接口
     * @Title: test
     * @Description: TODO
     * @param: @param signature
     * @param: @param timestamp
     * @param: @param nonce
     * @param: @param echostr
     * @param: @return
     * @return: String
     * @throws
     */
    @RequestMapping("/wx")
    public void test(HttpServletRequest request,HttpServletResponse response) {

        String msgSignature = request.getParameter("signature");
        String msgTimestamp = request.getParameter("timestamp");
        String msgNonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");
        PrintWriter print;
        if (WeixinCheckoutUtil.verifyUrl(msgSignature, msgTimestamp, msgNonce)) {
            try {
                print = response.getWriter();
                print.write(echostr);
                print.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

3、验证token,SHA-1算法

代码语言:javascript复制
/**
 * 签名认证工具类
 * @ClassName:  WeixinCheckoutUtil
 * @Description:TODO
 * @author: jp
 * @date:   2019年6月13日 下午4:56:12
 *
 * @Copyright: 2019 www.tydic.com Inc. All rights reserved.
 *
 */
public class WeixinCheckoutUtil {

    // 与公众号配置信息中的Token要一致
    private static String token = "";

    /**
     * 验证Token
     * @param msgSignature 签名串,对应URL参数的signature
     * @param timeStamp 时间戳,对应URL参数的timestamp
     * @param nonce 随机串,对应URL参数的nonce
     *
     * @return 是否为安全签名
     */
    public static boolean verifyUrl(String msgSignature, String timeStamp, String nonce) {
        String signature =getSHA1(token, timeStamp, nonce);
        if (!signature.equals(msgSignature)) {
            throw new AesException(AesException.ValidateSignatureError);
        }
        return true;
    }

    /**
     * 用SHA1算法验证Token
     *
     * @param token     票据
     * @param timestamp 时间戳
     * @param nonce     随机字符串
     * @return 安全签名
     */
    public static String getSHA1(String token, String timestamp, String nonce)  {
        try {
            String[] array = new String[]{token, timestamp, nonce};
            StringBuffer sb = new StringBuffer();
            // 字符串排序
            Arrays.sort(array);
            for (int i = 0; i < 3; i  ) {
                sb.append(array[i]);
            }
            String str = sb.toString();
            // SHA1签名生成
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            md.update(str.getBytes());
            byte[] digest = md.digest();

            StringBuffer hexstr = new StringBuffer();
            String shaHex = "";
            for (int i = 0; i < digest.length; i  ) {
                shaHex = Integer.toHexString(digest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexstr.append(0);
                }
                hexstr.append(shaHex);
            }
            return hexstr.toString();
        } catch (Exception e) {
            e.printStackTrace();
            //throw new AesException(AesException.ComputeSignatureError);
        }
        return null;
    }
}

0 人点赞