SpringMVC实现微信链接分享到朋友圈显示图片功能微信JS-SDK调用步骤
一、登录微信平台
login url:https://mp.weixin.qq.com/
name: your name
pwd: password
二、步骤 获取 access_token
1、登录平台
2、获取基本配置信息: 开发 --- 基本配置 , 获取信息如下:
- 开发者ID(AppID) : xxx。 (直接获取)
- 开发者密码(AppSecret):若忘记,需重置。 且需要管理员身份验证。 (xx)
- IP白名单:设置IP白名单后,获取 access_token接口才可调用成功。
3、获取 acccess_token: ( 获取文档 , 调试工具 )
- 请求方式: GET
- url: 获取URL
- 参数说明如下:
参数 | 是否必须 | 说明 |
grant_type | 是 | 获取access_token填写 client_credential |
appid | 是 | 第三方用户唯一凭证 |
secret | 是 | 第三方用户唯一凭证密钥,即appsecret |
三、设置 JS 接口安全域名 (文档 )
1、路径: 设置 --- 公众号设置 --- 功能设置 --- JS接口安全域名 。
2、需要先将 MP_verify*** 开头的文件上传到服务器,才能保存成功。
3、图片参考如下:
四、获取 jsapi_ticket
1、文档 : 【 附录1-JS-SDK使用权限签名算法】
2、请求方式: GET
3、url : 获取URL
4、参数: access_token 。 (获取方式: 【二-3】)
五、签名算法
1、文档 : 【签名算法】
2、签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。
3、步骤1:
jsapi_ticket=xxxx&noncestr=Wm3WZYTPz0wzccnW×tamp=1414587457&url=http://mp.weixin.qq.com?params=value
4、对string1进行sha1签名,得到 signature: (服务端实现)
5、注意事项如下:
- 签名用的noncestr和timestamp必须与 wx.config 中的nonceStr和timestamp相同。
- 签名用的url必须是调用JS接口页面的完整URL。
- 出于安全考虑,开发者必须在服务器端实现签名的逻辑。
- 如出现invalid signature 等错误详见附录5常见错误及解决办法。
6、微信 JS 接口签名校验工具: 签名校验
六、java版加密参考
1、定义 WeiXinConfig.java 存储相关配置信息 --- 主要字段参考
/**
* description: 微信配置相关 信息
* @version v1.0
* @author w
* @date 2019年2月22日下午3:12:11
**/
public class WeiXinConfig {
private String timestamp = DateUtils.getDate("yyyyMMdd"); // 生成签名的时间戳
private String noncestr = "HaHa_Sir" ; // 生成签名的随机串
private String signature ; // 签名
private String ticket ; //
private String url ; // 当前页面 url
// ============= getter , setter ================= //
}
2、定义WeiXinUtils.java 实现 微信 signature 签名算法 sha-1 加密
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.slf4j.Logger;
/**
* description: 微信 signature 签名算法 sha-1 加密
* @version v1.0
* @author w
* @date 2019年2月25日下午5:24:53
**/
public class WeiXinUtils {
private static final Logger logger = org.slf4j.LoggerFactory.getLogger(WeiXinUtils.class);
/**
* description: 获取微信签名加密后的字符串
* @return String
* @version v1.0
* @author w
* @date 2019年2月25日 下午5:26:39
*/
public static String signature( String str) {
MessageDigest messageDigest = null ;
logger.info("signature str :" + str);
try {
messageDigest = MessageDigest.getInstance("SHA-1");
byte[] digest = messageDigest.digest(str.getBytes());
return byteToStr(digest).toLowerCase();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
/**
* description: 微信 sha-1 加密后字符串返回
* @param config
* @return String
* @version v1.0
* @author w
* @date 2019年2月25日 下午5:35:14
*/
public static String signature(WeiXinConfig config) {
String str = concatStr(config);
return signature(str);
}
/**
* description: 需要加密的参数,字符串拼接
* @param config
* @return String
* @version v1.0
* @author w
* @date 2019年2月25日 下午5:42:28
*/
public static String concatStr(WeiXinConfig config) {
StringBuffer sb = new StringBuffer();
sb.append("jsapi_ticket=").append(config.getTicket()).append("&");
sb.append("noncestr=").append(config.getNoncestr()).append("&");
sb.append("timestamp=").append(config.getTimestamp()).append("&");
sb.append("url=").append(config.getUrl());
return sb.toString();
}
/**
* 将字节数组转换为十六进制字符串
* @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;
}
}
七、SpringMVC提供微信配置相关信息
1、提供微信配置相关信息
/**
* description: 获取微信 config 相关的配置信息
* @param config
* @return WeiXinConfig
* @version v1.0
* @author w
* @date 2019年2月26日 上午11:49:27
*/
@RequestMapping(value = { "/weixin/config"})
@ResponseBody
public WeiXinConfig configInfo(WeiXinConfig config) {
config.setTicket(JsapiTicketUtil.getJsapiTicket());
String signature = WeiXinUtils.signature(config);
config.setSignature(signature);
return config;
}
八、前端调用相关配置信息
1、引入依赖 js 文件
<script src="/js/jquery-1.8.3.min.js" type="text/javascript" charset="utf-8"></script>
<script src="http://res.wx.qq.com/open/js/jweixin-1.4.0.js" type="text/javascript"></script>
2、前端调用相关配置信息
<script type="text/javascript">
var url = location.href.split('#')[0];
$.ajax({
url : '${ctx}/weixin/config',
type:'post',
data:{"url":url},
cache:false,
success:function(data){
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参
appId: data.appId, // 必填,公众号的唯一标识
timestamp:data.timestamp , // 必填,生成签名的时间戳
nonceStr: data.noncestr, // 必填,生成签名的随机串
signature:data.signature, // 必填,签名
jsApiList: ["checkJsApi","onMenuShareTimeline","onMenuShareAppMessage" ,"updateTimelineShareData"] // 必填,需要使用的JS接口列表
});
}
});
wx.ready(function () { //需在用户可能点击分享按钮前就先调用
// 获取“分享到朋友圈”按钮点击状态及自定义分享内容接口(即将废弃)
wx.onMenuShareTimeline({
title: "分享标题123321", // 分享标题
link: location.href, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: 'http://xx.com/static/img/vx-logo.jpg', // 分享图标
success: function () {
// 分享成功,可进行分享数据统计
}
});
// 获取“分享给朋友”按钮点击状态及自定义分享内容接口(即将废弃)
wx.onMenuShareAppMessage({
title: $("head>title").text(), // 分享标题
desc: $("#span_description").text(), // 分享描述
link: location.href, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: 'http://xx.com/static/img/vx-logo.jpg', // 分享图标
type: 'link', // 分享类型,music、video或link,不填默认为link
dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
success: function () {
// 用户点击了分享后执行的回调函数
}
});
});
</script>
九、功能测试
1、功能开发完成后,需部署到 【三-设置 JS 接口安全域名】的服务器下。
2、将已经配置分享功能页面URL粘贴到 微信web开发者工具 、或使用 扫一扫 二维码、或将URL发送到微信中打开。
3、微信web开发者工具 调试截图如下:
4、微信使用JS-SDK分享前后对比
十、总结
1、主要步骤如下:
- 获取 AppID 、 AppSecret 、添加IP白名单
- 获取access_token , 获取 jsapi_ticket
- 实现 signature sha-1 签名算法加密
- 前端调用配置信息
- 功能测试
2、获取 access_token 、jsapi_ticket 可在java服务端封装对应工具类进行获取。 如: HttpClient , java原生的 HttpURLConnection 等等。
3、微信开发文档中要求缓存 access_token,可使用 Redis , Ehcache 来实现,或者自行定义 静态全局变量也可以。 为了便于理解,本示例中没有提供。
4、调试过程中遇到错误请参考: 附录5-常见错误及解决方法 (tips: Ctrl+F ,快速定位)
5、上一操作错误都排除后,还是遇到 invalid signature 错误,请参考:invalid signature 签名无效 解决思路 。
十一、参考资料
1、 官方文档
3、微信web开发者工具 、Windows 64位版本 、 Windows 32位版本 、 Mac版本