签名错误的终极解决方案!jsapi 错误码:63002,invalid signature

问题效果如下

返回错误详细信息

errMsg: "config:fail,Error: 系统错误,错误码:63002,invalid signature [20201105 15:06:48][]"

通过config接口注入权限验证配置ready方法一直返回错误。
接口文档地址: https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#4
遗憾这里这有前端的文档调用说明,没找到后台调用获取jsapi_ticket的方法。
后台用java调用获取如下参数:

wx.config({
  debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
  appId: '', // 必填,公众号的唯一标识
  timestamp: , // 必填,生成签名的时间戳
  nonceStr: '', // 必填,生成签名的随机串
  signature: '',// 必填,签名
  jsApiList: [] // 必填,需要使用的JS接口列表
});

后台java调用

package com.cciinet.shop.controller.common.wechat;

import com.alibaba.fastjson.JSONObject;
import com.cciinet.shop.util.HttpRequest;
import lombok.extern.slf4j.Slf4j;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.UUID;

/**
 * @Author: 
 * @Date: 2020/6/10
 * @ClassName: Sign
 * @Description: TODO
 **/
@Slf4j
public class Sign {
    /**
     * jsSdk 获取微信config
     *
     * @param url
     * @return
     */
    public  JsSdk sign(String url,String appId, String appsecret) {
        String jsapi_ticket = getJsapiTicket(appId,appsecret);
        JsSdk jsSdk = new JsSdk();
        jsSdk.setAppid(appId);
        jsSdk.setUrl(url);
        String nonce_str = create_nonce_str();
        jsSdk.setNoncestr(nonce_str);
        String timestamp = create_timestamp();
        jsSdk.setTimestamp(timestamp);
        String signature = "";
        //注意这里参数名必须全部小写,且必须有序
        String string1 = "jsapi_ticket=" + jsapi_ticket +
                "&noncestr=" + nonce_str +
                "&timestamp=" + timestamp +
                "&url=" + url;
        try {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(string1.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());
            jsSdk.setSignature(signature);
        } catch (NoSuchAlgorithmException e) {
            jsSdk = null;
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            jsSdk = null;
            e.printStackTrace();
        }
        return jsSdk;
    }

    /**
     * 生成随机数
     *
     * @return
     */
    private static String create_nonce_str() {
        return UUID.randomUUID().toString().substring(0, 20);
    }

    /**
     * 当前日期字符串生成
     *
     * @return
     */
    private static String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }

    /**
     * @param hash
     * @return
     */
    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;
    }

    public  String getJsapiTicket(String appId, String appsecret) {
        String requestUrl = "https://api.weixin.qq.com/cgi-bin/token";
        String params = "grant_type=client_credential&appid=" + appId + "&secret=" + appsecret+ "";
        String result = HttpRequest.sendGet(requestUrl , params);
        String access_token = JSONObject.parseObject(result).getString("access_token");
        requestUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
        params = "access_token=" + access_token + "&type=jsapi";
        result = HttpRequest.sendGet(requestUrl , params);
        String jsapi_ticket = JSONObject.parseObject(result).getString("ticket");
        log.info("jsapi_ticket=" + jsapi_ticket);
        return  jsapi_ticket;
    }

    public static void main(String[] args) {
        Sign sign = new Sign();
        String appId = "";
        String appSecret = "";
//        String jsapiTicket = sign.getJsapiTicket(appId, appSecret);
//        System.out.println(jsapiTicket);
        String url = "";
        JsSdk jsSdk = sign.sign(url, appId, appSecret);
        System.out.println(jsSdk.toString());
    }
}

其中main方法里输入自己公众号的appid,secret,和分享要调用的url。调用即可拿到返回值。 大坑来了,我的问题是用后代代码生成的signature和用微信在线调试工具生成的signature是一样的。
微信在线调试地址:http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign
但仍然提示签名错误。奇了怪了。
最后发现是我程序后台调用生成签名传入的url不对。
传入的url应该是当前要分享的页面的完整url,网上还有好多说要在url后边加上个“/”个,这个也不对,不应该加斜杠的。
总结一下: 这个报签名不对的原因,并不是后台代码调用微信接口返回signature和在线微信调试生成的signature对不上。而是实际调用微信接口页面地址和生成签名传入的url对不上导致的。
看下接口说明,后台调用微信接口的文档没找到o(╯□╰)o
这里明确说明了是发起页面的完整url.。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章