企业微信开发:使用 JS-SDK 配置 wx.config 实现屏蔽分享菜单功能(五)

前言

  本文主题是配置 wx.config 实现“屏蔽企业微信分享功能”,原本我以为这个企业微信屏蔽分享功能和微信应该差不多,等到我真正配置去写的时候才发现。。这玩意坑还挺多,写篇文章记录一下自己踩过的坑,希望对你们有所帮助!

概述

  先简单说一下什么 JS-SDK 的作用,企业微信 JS-SDK 是企业微信面向网页开发者提供的基于企业微信内的网页开发工具包,具体详情查看企业微信官方文档:JS-SDK
  关于微信和企业微信调用屏蔽功能之间的区别:微信内置浏览器有自带的私有接口可直接调用 WeixinJSBridge(关于这个接口的介绍可查看博主的上一篇文章“微信开发:屏蔽分享功能”)我原本以为这个接口是企业微信和微信可以共用的后来才发现,这个接口仅限于“微信内置浏览器”
  测试工具及文档
    1.签名效验工具
    2.wx.config 配置文档
    3.JS-SDK使用权限签名算法
    3.JS-SDK Demo

配置 wx.config

  第一步:引入 jweixin-1.2.0.js 文件,在那个页面用就引入到那个页面,(支持 https):点击下载注意这个地方不支持微信的 jweixin-1.6.0.js 版本

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

  第二步:配置 wx.config,这个地方有个需要注意的点,为了安全起见不建议使用 ajax 回调的方式获取签名参数,推荐进入页面时获取。

wx.config({
    beta: true,// 必须这么写,否则wx.invoke调用形式的jsapi会有问题
    debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    appId: '', // 必填,企业微信的corpID
    timestamp: , // 必填,生成签名的时间戳
    nonceStr: '', // 必填,生成签名的随机串
    signature: '',// 必填,签名,见 附录-JS-SDK使用权限签名算法
    jsApiList: [] // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来
});

  第三步:这个地方比较重要,所有调用的 wx.config 成功的接口一定要写到这个里边 wx.ready(),相当于是一个处理成功验证

wx.ready(function(){
    // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
});

  第四步:这个就没啥好介绍的。。error 接口处理失败验证

wx.error(function(res){
    // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
});

  具体参数的介绍差不多也就这些。。下边就是我们的实践操作

代码片段

  这个地方我们先写后台获取签名等配置,这个地方的配置参数要和我们 wx.config 对应,一定不要错!!
  1.获取 timestamp 参数(获取随机时间戳)

// 时间戳
String timestamp = Long.toString((new Date().getTime()) / 1000);

  2.获取 nonceStr 参数(获取随机字符串)

// 随机串
String nonceStr = UUID.randomUUID().toString();

  3.获取 ticket 参数,先获取 access_tocken,然后通过 tocker 参数获取 ticket,获取 tocken 可借鉴 企业微信开发:access_tocken

// 获取 access_token
AccessToken accessToken = AccessTokenAPI.getAccessToken(CORPID,SECRET);
// 根据 tocker 获取 jstl
String urlStr = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token="+accessToken.getToken();
JSONObject jsonObject = HttpRequestUtil.httpRequest(urlStr, EnumMethod.GET.name(), null);
String ticket = jsonObject.getString("ticket");

  4.获取 signature 参数,signature 参数是通过“随机字符串+ticket+随机时间戳+当前页面路径”进行 sha1 加密得来的值,这个地方最需要注意的就是你的 url 参数,一定是获取当前页面的 url !!! 并且必须是可信域名,关于可信域名配置可借鉴:企业微信开发:自建应用配置可信域名

String signature = getsig(nonceStr,ticket,timestamp,url);

  已使用的工具类

// 使用随机字符串+ticket+随机时间戳+当前页面路径
public static String getsig(String noncestr,String jsapi_ticket,String timestamp,String url){
	String[] paramArr = new String[] { "jsapi_ticket=" + jsapi_ticket,
			"timestamp=" + timestamp, "noncestr=" + noncestr, "url=" + url };
	Arrays.sort(paramArr);
	// 将排序后的结果拼接成一个字符串
	String content = paramArr[0].concat("&"+paramArr[1]).concat("&"+paramArr[2])
			.concat("&"+paramArr[3]);
	String gensignature = null;
	try {
		MessageDigest md = MessageDigest.getInstance("SHA-1");
		// 对拼接后的字符串进行 sha1 加密
		System.out.println("拼接加密签名:"+content.toString());
		byte[] digest = md.digest(content.toString().getBytes());
		gensignature = byteToStr(digest);
	} catch (NoSuchAlgorithmException e) {
		e.printStackTrace();
	}
	// 将 sha1 加密后的字符串与 signature 进行对比
	if (gensignature != null) {
		return gensignature;// 返回signature
	} else {
		return "false";
	}
}

/**
 * 将字节数组转换为十六进制字符串
 *
 * @param byteArray
 * @return
 */
private static String byteToStr(byte[] byteArray) {
	String strDigest = "";
	for (int i = 0; i < byteArray.length; i++) {
		strDigest += byteToHexStr(byteArray[i]);
	}
	return strDigest;
}

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

  到这后台的配置就算是完成了,我们看一下完整的后台代码

@Controller
@RequestMapping("/index")
public class TestController {

    private String CORPID = "xxxxx";

    private String SECRET = "xxxxx";

    // 跳转到主页
    @RequestMapping(value = "getIndex",method = {RequestMethod.GET,RequestMethod.POST})
    public String getIndex( Model model){
        Map<String,Object> map = signature(request);
        model.addAttribute("appId",map.get("appId"));
        model.addAttribute("timestamp",map.get("timestamp"));
        model.addAttribute("nonceStr",map.get("nonceStr"));
        model.addAttribute("signature",map.get("signature"));
        return "index";
    }
	
	// 获取签名方法
    private Map<String,Object> signature(HttpServletRequest request){
        String url = "http://linluochen.cn"+request.getRequestURI();
        request.getRequestURL().toString();
        Map<String,Object> map = new HashMap<String,Object>();
        // 时间戳
        String timestamp = Long.toString((new Date().getTime()) / 1000);
        // 随机串
        String nonceStr = UUID.randomUUID().toString();
        // 获取 access_token
        AccessToken accessToken = AccessTokenAPI.getAccessToken(CORPID,SECRET);
        // 根据 tocker 获取 jstl
        String urlStr = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token="+accessToken.getToken();
        JSONObject jsonObject = HttpRequestUtil.httpRequest(urlStr, EnumMethod.GET.name(), null);
        String ticket = jsonObject.getString("ticket");
        System.out.println("要加密的参数:"+nonceStr+" "+ticket+" "+timestamp+" "+url);
        String signature = getsig(nonceStr,ticket,timestamp,url);
        map.put("appId",CORPID);
        map.put("timestamp",timestamp);
        map.put("nonceStr",nonceStr);
        map.put("signature",signature);
        System.out.println("返回结果Map:"+map);
        return map;
    }


	// 使用随机字符串+ticket+随机时间戳+当前页面路径
    public static String getsig(String noncestr,String jsapi_ticket,String timestamp,String url){
        String[] paramArr = new String[] { "jsapi_ticket=" + jsapi_ticket,
                "timestamp=" + timestamp, "noncestr=" + noncestr, "url=" + url };
        Arrays.sort(paramArr);
        // 将排序后的结果拼接成一个字符串
        String content = paramArr[0].concat("&"+paramArr[1]).concat("&"+paramArr[2])
                .concat("&"+paramArr[3]);
        String gensignature = null;
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            // 对拼接后的字符串进行 sha1 加密
            System.out.println("拼接加密签名:"+content.toString());
            byte[] digest = md.digest(content.toString().getBytes());
            gensignature = byteToStr(digest);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        // 将 sha1 加密后的字符串与 signature 进行对比
        if (gensignature != null) {
            return gensignature;// 返回signature
        } else {
            return "false";
        }
    }

    /**
     * 将字节数组转换为十六进制字符串
     *
     * @param byteArray
     * @return
     */
    private static String byteToStr(byte[] byteArray) {
        String strDigest = "";
        for (int i = 0; i < byteArray.length; i++) {
            strDigest += byteToHexStr(byteArray[i]);
        }
        return strDigest;
    }

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

}

  最后我们配置一下前台页面的代码(我就直接贴代码片段了,就不整个页面的放了)

wx.config({
	debug: false,//生产环境需要关闭debug模式
	appId: "[[${appId}]]",//appId通过微信服务号后台查看
	timestamp: "[[${timestamp}]]",//生成签名的时间戳
	nonceStr: "[[${nonceStr}]]",//生成签名的随机字符串
	signature: "[[${signature}]]",//签名
	jsApiList: [//需要调用的JS接口列表
		'hideOptionMenu', // 隐藏菜单
	]
});

wx.ready(function(){
	wx.hideOptionMenu(); // 验证成功后调用隐藏菜单的方法
});

测试

  测试结果都是大差不差的一样
在这里插入图片描述

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
步骤一:引入JS文件 在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.2.0.js 备注:支持使用 AMD/CMD 标准模块加载方法加载 步骤二:通过config接口注入权限验证配置 所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。 wx.config({ debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: '', // 必填,企业号的唯一标识,此处填写企业号corpid timestamp: , // 必填,生成签名的时间戳 nonceStr: '', // 必填,生成签名的随机串 signature: '',// 必填,签名,见附录1 jsApiList: [] // 必填,需要使用JS接口列表,所有JS接口列表见附录2 }); 步骤三:通过ready接口处理成功验证 wx.ready(function(){ // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。 }); 步骤四:通过error接口处理失败验证 wx.error(function(res){ // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。 }); 接口调用说明 所有接口通过wx对象(也可使用jWeixin对象)来调用,参数是一个对象,除了每个接口本身需要传的参数之外,还有以下通用参数: success:接口调用成功时执行的回调函数。 fail:接口调用失败时执行的回调函数。 complete:接口调用完成时执行的回调函数,无论成功或失败都会执行。 cancel:用户点击取消时的回调函数,仅部分有用户取消操作的api才会用到。 trigger: 监听Menu中的按钮点击时触发的方法,该方法仅支持Menu中的相关接口。
好的,关于微信分享的问题,我可以给你一些指导。首先,你需要在你的 HTML5 页面中引入微信 JS-SDK,然后在页面加载完成后初始化 JS-SDK。接着,你需要通过 JS-SDK 提供的接口来配置分享的内容和参数,最后调用分享接口即可完成分享。 具体步骤如下: 1. 引入微信 JS-SDK 在 HTML 页面中引入微信 JS-SDK,如下所示: ```html <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script> ``` 2. 初始化 JS-SDK 在页面加载完成后,初始化 JS-SDK。你需要先通过微信公众平台获取到你的 AppID 和 AppSecret,然后使用这些信息初始化 JS-SDK。示例代码如下: ```javascript wx.config({ debug: false, appId: 'your app id', timestamp: 'your timestamp', nonceStr: 'your nonceStr', signature: 'your signature', jsApiList: [ 'onMenuShareAppMessage', 'onMenuShareTimeline', 'onMenuShareQQ', 'onMenuShareWeibo', 'onMenuShareQZone' ] }); ``` 其中,`appId`、`timestamp`、`nonceStr` 和 `signature` 分别是通过微信公众平台生成的,用于验证你的身份和权限的参数。`jsApiList` 是你需要使用JS-SDK 接口列表。 3. 配置分享内容和参数 在初始化 JS-SDK 后,你需要通过 JS-SDK 提供的接口来配置分享的内容和参数。示例代码如下: ```javascript wx.ready(function() { wx.onMenuShareAppMessage({ title: '分享标题', desc: '分享描述', link: '分享链接', imgUrl: '分享缩略图', trigger: function(res) {}, success: function(res) {}, cancel: function(res) {}, fail: function(res) {} }); wx.onMenuShareTimeline({ title: '分享标题', link: '分享链接', imgUrl: '分享缩略图', trigger: function(res) {}, success: function(res) {}, cancel: function(res) {}, fail: function(res) {} }); }); ``` 其中,`onMenuShareAppMessage` 和 `onMenuShareTimeline` 分别是分享给好友和分享到朋友圈的接口。你需要提供分享的标题、描述、链接和缩略图等参数。 4. 调用分享接口 最后,在页面中调用分享接口即可完成分享。示例代码如下: ```javascript wx.ready(function() { wx.onMenuShareAppMessage({ title: '分享标题', desc: '分享描述', link: '分享链接', imgUrl: '分享缩略图', trigger: function(res) {}, success: function(res) {}, cancel: function(res) {}, fail: function(res) {} }); wx.onMenuShareTimeline({ title: '分享标题', link: '分享链接', imgUrl: '分享缩略图', trigger: function(res) {}, success: function(res) {}, cancel: function(res) {}, fail: function(res) {} }); // 在需要分享的地方调用 shareAppMessage 和 shareTimeline 接口 // 示例代码如下 document.querySelector('#share-btn').addEventListener('click', function() { wx.shareAppMessage({ title: '分享标题', desc: '分享描述', link: '分享链接', imgUrl: '分享缩略图', trigger: function(res) {}, success: function(res) {}, cancel: function(res) {}, fail: function(res) {} }); }); document.querySelector('#share-timeline-btn').addEventListener('click', function() { wx.shareTimeline({ title: '分享标题', link: '分享链接', imgUrl: '分享缩略图', trigger: function(res) {}, success: function(res) {}, cancel: function(res) {}, fail: function(res) {} }); }); }); ``` 这样就完成了微信分享功能实现。需要注意的是,由于微信的安全机制,分享的链接必须是在微信公众平台中配置过的域名,否则可能无法正常分享

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

平凡的人类

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值