微信开发配置JSSDK,注入权限验证,以及invalid signature签名错误解决

在微信开发中很多功能都要用到微信JSSDK,关于JSSDK的使用,微信官方的文档已经比较详细,但是我配置好后,使用谷歌浏览器访问都不报错,使用微信客户端就一直报签名错误。

在仔细排查前5条后,都没有发现问题,这里要注意的是,在微信浏览器里,微信客户端会给你的连接转码,这里把连接提交到后台的时候一定要用encodeURIComponent。然后后台(Java)需要使用

URLDecoder.decode(url, “UTF-8”);解码!!!!!

步骤:

前提公众号已配置好js安全域名,
在需要调用JS接口的页面引入如下JS文件:

<script src="http://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>

通过config接口注入权限验证配置

'use strict';
$(function () {
    //初始化微信js授权
    initWxJsConfig();
});
//授权当前页面有js权限
function initWxJsConfig() {
    ajaxSyncPost(ctx + "weChat/getConfig",{url: encodeURIComponent(location.href.split('#')[0])},function(data) {
    //    encodeURIComponent这里编码后,在后台需要解码**********
        wx.config({
            debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
            appId: data.appid, // 必填,公众号的唯一标识
            timestamp: data.timestamp, // 必填,生成签名的时间戳
            nonceStr: data.nonceStr, // 必填,生成签名的随机串
            signature: data.signature,// 必填,签名,见附录1
            // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
            jsApiList: ['checkJsApi', 'onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo', 'onMenuShareQZone', 'hideMenuItems', 'showMenuItems', 'hideAllNonBaseMenuItem', 'showAllNonBaseMenuItem', 'translateVoice', 'startRecord', 'stopRecord', 'onVoiceRecordEnd', 'playVoice', 'onVoicePlayEnd', 'pauseVoice', 'stopVoice', 'uploadVoice', 'downloadVoice', 'chooseImage', 'previewImage', 'uploadImage', 'downloadImage', 'getNetworkType', 'openLocation', 'getLocation', 'hideOptionMenu', 'showOptionMenu', 'closeWindow', 'scanQRCode', 'chooseWXPay', 'openProductSpecificView', 'addCard', 'chooseCard', 'openCard']
        });

        wx.ready(function() {
                wx.checkJsApi({
                    jsApiList : ['scanQRCode'],
                    success : function(res) {

                    }
                });
            // 9.1.2 扫描二维码并返回结果
            $("#scanQRCode").click(function(){
                alert(wx.config);
                wx.scanQRCode({
                    needResult: 1,// 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
                    scanType: ["barCode"],// 可以指定扫二维码还是一维码,默认二者都有
                    success: function (res) {
                        //扫码后获取结果参数赋值给Input
                        debugger
                        let url = res.resultStr; // 当needResult 为 1 时,扫码返回的结果
                        //商品条形码,取","后面的
                        if (url.indexOf(",") >= 0) {
                            let tempArray = url.split(',');
                            let barCode = tempArray[1];
                            selectByMeterNo(barCode);//根据条形码做自己的业务操作
                        } else {
                            alert("请对准条形码扫码!");
                        }
                    },
                    error : function(){
                        console.log('扫描出错');
                    }
                });
            });
        });

        wx.error(function(res) {
            alert("调用微信jsapi返回的状态:" + res.errMsg);//这个地方的好处就是wx.config配置错误,会弹出窗口哪里错误,然后根据微信文档查询即可。
        });
         
    })
}

java后台:

@Controller
@RequestMapping("/weChat")
public class WxConfigController {
    @Autowired
    protected WxMpService wxMpService;//微信公众号API的Service.
    private static final Logger log = LoggerFactory.getLogger(WxConfigController.class);
/**
  
     * @param url url
     */
    @PostMapping("/getConfig")
    @ResponseBody
    public AjaxResult getConfig(HttpServletResponse response, @RequestParam(value = "url") String url) {
        log.info("Url:*********" + url);
        try {
            url = URLDecoder.decode(url, "UTF-8");// 解码
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        log.info("decodeUrl:*********" + url);
        String jsapi_ticket = "jsapi_ticket";
        try {
            jsapi_ticket = this.wxMpService.getJsapiTicket();
            log.info("JsapiTicket:*********" + jsapi_ticket);
            log.info("AccessToken:*********" + this.wxMpService.getAccessToken());
        } catch (WxErrorException e) {
            e.printStackTrace();
        }
        AjaxResult ajaxResult = AjaxResult.success();
        String nonce_str = create_nonce_str();
        String timestamp = create_timestamp();
        String string1;
        String signature = "";

        //注意这里参数名必须全部小写,且必须有序
        string1 = "jsapi_ticket=" + jsapi_ticket +
                "&noncestr=" + nonce_str +
                "×tamp=" + timestamp +
                "&url=" + url;
        log.info("string1:*********" + string1);

        try {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(string1.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());

//            if (!wxService.checkSignature(timestamp, nonce, signature)) {
//                throw new IllegalArgumentException("非法请求,可能属于伪造的请求!");
//            }
//

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

        ajaxResult.put("url", url);
        ajaxResult.put("jsapi_ticket", jsapi_ticket);
        ajaxResult.put("nonceStr", nonce_str);
        ajaxResult.put("timestamp", timestamp);
        ajaxResult.put("signature", signature);
        ajaxResult.put("appid", this.wxMpService.getWxMpConfigStorage().getAppId());
        log.info("APPID:*********" + this.wxMpService.getWxMpConfigStorage().getAppId());
        log.info("signature:*********" + signature);
        log.info(ajaxResult.toString());
        return ajaxResult;
    }
    private static String create_nonce_str() {
        return UUID.randomUUID().toString();
    }

    private static String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }


    private static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash) {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }

    /**
     * 将字节转换为十六进制字符串
     *
     * @param mByte
     * @return
     */
    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;
    }

    }

重启启动服务,OK。

你可能感兴趣的:(报错日志记录,java)