微信公众号JS-SDK获取signature签名及配置config

申屠秦斩
2023-12-01

微信官方文档地址 点击跳转

JSSDK使用的公众号配置请查看官方微信文档,我就不进行过多的赘述了。

使用JS-SDK的页面必须先注入配置信息:js代码

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

获取signature主要分4个步骤
1、使用APPID和APPSecret获取access_token;(access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效
2、使用access_token获取jsapi_ticket ;
3、用时间戳、随机数、jsapi_ticket和要访问的url按照签名算法拼接字符串;
4、对第三步的字符串进行SHA1加密,得到签名。

注意事项:

1、签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。
2、签名用的url必须是调用JS接口页面的完整URL。
3、出于安全考虑,开发者必须在服务器端实现签名的逻辑。

第一步:获取access_token(需要在服务器上 )

/**
 * 获取accessToken
 * @author myc
 */
public class GetAccessTokenUtil {
    // 网页授权接口
    public final static String AccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET";
    public static Map<String, String> getAccessToken(String appid, String appsecret) {
        String requestUrl = AccessTokenUrl .replace("APPID", appid).replace("SECRET", appsecret);
        HttpClient client = null;
        Map<String, String> result = new HashMap<String, String>();
        String accessToken = null;
        try {
            client = new DefaultHttpClient();
            HttpGet httpget = new HttpGet(requestUrl);
            ResponseHandler<String> responseHandler = new BasicResponseHandler();
            String response = client.execute(httpget, responseHandler);
            JSONObject OpenidJSON = JSONObject.fromObject(response);
            accessToken = String.valueOf(OpenidJSON.get("access_token"));
            result.put("accessToken", accessToken);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            client.getConnectionManager().shutdown();
        }
        return result;
    }
}


第二步:获取jsapi_ticket
/**
 * @description 获取ticket
 * @author myc
 */
public class JsapiTicketUtil {
    // 网页授权接口
    public final static String AccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";

    public static Map<String, String> JsapiTicket(String accessToken) {
        String requestUrl = AccessTokenUrl .replace("ACCESS_TOKEN", accessToken);
        HttpClient client = null;
        Map<String, String> result = new HashMap<String, String>();
        try {
            client = new DefaultHttpClient();
            HttpGet httpget = new HttpGet(requestUrl);
            ResponseHandler<String> responseHandler = new BasicResponseHandler();
            String response = client.execute(httpget, responseHandler);
            JSONObject openidJSON = JSONObject.fromObject(response);
            String errcode = String.valueOf(openidJSON.get("errcode"));
            String errmsg = String.valueOf(openidJSON.get("errmsg"));
            String ticket = String.valueOf(openidJSON.get("ticket"));
            String expires_in = String.valueOf(openidJSON.get("expires_in"));
            result.put("errcode", errcode);
            result.put("errmsg", errmsg);
            result.put("ticket", ticket);
            result.put("expires_in", expires_in);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            client.getConnectionManager().shutdown();
        }
        return result;
    }
}
第三步:用时间戳、随机数、jsapi_ticket和要访问的url按照签名算法拼接字符串
String noncestr = this.randomUUID();//随机字符串
String timestamp = String.valueOf(System.currentTimeMillis());//时间戳
//4获取url
根据项目需要获取对应的url地址
//5、将参数排序并拼接字符串
String str = "jsapi_ticket="+ticket+"&noncestr="+noncestr+"&timestamp="+timestamp+"&url="+url;

/**
* @return String 随机字符串
*/
public static String randomUUID() {
	String uuid = UUID.randomUUID().toString();
    //去掉“-”符号 
    return uuid.replaceAll("-", "");
}
第四步:对第三步的字符串进行SHA1加密,得到签名,并返回结果
String str = "jsapi_ticket="+ticket+"&noncestr="+noncestr+"&timestamp="+timestamp+"&url="+url;
//6、将字符串进行sha1加密
String signature = SHA1(str);
Map<String,String> map=new HashMap();
map.put("timestamp",timestamp);
map.put("accessToken",accessToken);
map.put("ticket",ticket);
map.put("noncestr",noncestr);
map.put("signature",signature);
    public static String SHA1(String decript) {
        try {
            MessageDigest digest = java.security.MessageDigest.getInstance("SHA-1");
            digest.update(decript.getBytes());
            byte messageDigest[] = digest.digest();
            // Create Hex String
            StringBuffer hexString = new StringBuffer();
            // 字节数组转换为 十六进制 数
            for (int i = 0; i < messageDigest.length; i++) {
                String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexString.append(0);
                }
                hexString.append(shaHex);
            }
            return hexString.toString();

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }
测试
{
	"timestamp":"1645167619599"
	"noncestr":"8541cd74fb95e329"
	"accessToken":"9_hfseYdankaddajsndjsndjas-kedmadkhkea"
	"ticket":"adcwDFJLKDJFKDSJKAjkldjfjksdlllJKDJF"
	"signature":"jdksa2e3224324jkldjkjsaldjsalkjdsajdksajdsajk "
}
签名获取成功之后,前端js配置文件如图示
wx.config({  
    debug: true, //调试阶段建议开启  
    appId: "APPID",//APPID  
    timestamp: "timestamp",//上面main方法中拿到的时间戳timestamp  
    nonceStr: "nonceStr",//上面main方法中拿到的随机数nonceStr  
    signature: "signature",//上面main方法中拿到的签名signature  
    jsApiList: [  
           //所有要调用的 API 都要加到这个列表中  
           "chooseImage"//需要检测的JS接口列表  
    ]  
});  

以上的时间戳、随机数、签名一定要跟main方法中获取到的一致,否则会报invalid signature错误。

签名的有效时间为7200秒,也就是2个小时,因此当超过两个小时候,再访问也会报invalid signature错误。

还有一个错误:invalid url domain 这个跟生成签名时用的url有关系,官网的说法是:
invalid url domain当前页面所在域名与使用的appid没有绑定,请确认正确填写绑定的域名,如果使用了端口号,则配置的绑定域名也要加上端口号(一个appid可以绑定三个有效域名)
这个url必须是:“公众号设置—功能设置----JS接口安全域名”中绑定的三个域名之一
访问的时候,就会出现一个config:ok,这就说明配置成功了。

 类似资料: