相关参考网址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115
终极效果:

背景介绍:
在我们使用微信浏览器进行浏览网页的时候,有时会有一些需求是要求你所查看的页面可以通过微信分享出去,然而普通的网页,在微信的浏览器中点击分享出去的效果,由于微信自己的一些限制,会导致分享出去的页面并不能达到上图的效果,实际的效果可能是下图这样的,很扯

想要达成想要的那种效果,就必须集成微信官方的 JSSDK:


具体步骤
一、服务器端操作
登录微信公共平台使用开发者账户登录到后台管理系统页面

按照下面叙述的步骤绑定想要绑定的服务器域名

服务器端
一般的获取验证签名步骤如下:
step1: 使用微信公众号的 APPID 和 APPKEY 在微信的官方接口中获取到应用的 Access_token 网址为
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=YOURAPPID&secret=YOURAPPSECRET
其中将 YOURAPPID 和 YOURAPPSECRRET 换成公众号的 APPID 和 APPSECRET 即可,成功后的效果会返回你的 access_token

step2:使用 step1 中生成的 access_token 在下面链接中获取到最终签名用的 ticket
https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=access_tokenInStep1&type=jsapi
如下图
最终的流程中,我们即可使用这个 ticket 进行对网页的签名
由于整个流程中生成的各个关键码 ,微信都给其设定了时间限制,对于每个时间的使用有效期,都只有 7200 秒,也就是两个小时,所以这些码子必须通过数据库存储的方式存储进数据库,然后定时对其更新,保证每个码子都可以进行有效的签名,具体实际的流程如下:
step1:将 AppId 和 AppKey 存储到数据库 appconfig 里面,更新的代码如下
public void UpdateAccess_tokenAndTicket(){
//获取到AppId 和AppSecret
String appId = configRepository.findByName("WXJSSDKID").getValue();
String appsecret = configRepository.findByName("WXJSSDKSECRET").getValue();
//根据Appid 和Appsecret生成Access token 和ticket
//先更新ACCESS_TOKEN的code
Config config_access_token = configRepository.findByName("ACCESS_TOKEN");
String token_code = WxJSSDKUtil.getAccess_token(appId, appsecret);
if(StringUtils.isNotBlank(token_code)){
config_access_token.setValue(token_code);
configRepository.save(config_access_token);
//根据access获取到ticket并更新他
Config config_ticket = configRepository.findByName("TICKET");
System.out.println("================="+token_code);
String ticket = WxJSSDKUtil.GetTicket(token_code);
if(StringUtils.isNotBlank(ticket)){
System.out.println("new ticket======"+ticket);
config_ticket.setValue(ticket);
configRepository.save(config_ticket);
}
}
}
这里需要调用获取 access_token 和 Ticket 的方法
public class WxJSSDKUtil {
private final static String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";
private final static String TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
/**
* 根据appid和appsecret获取access_token
* @param appid
* @param appsecret
* @return
*/
/**
*获取ACCESSTOKEN
*/
@SuppressWarnings("unchecked")
public static String getAccess_token(String appid, String appsecret){
String param = "grant_type=client_credential&appid="+appid+"&secret="+appsecret;
String res = HttpUtils.sendGet(ACCESS_TOKEN_URL, param);
Map resObj = JSONObject.fromObject(res);
String access_token = (String) resObj.get("access_token");
return access_token;
}
/**
*获取ticket
*/
@SuppressWarnings("unchecked")
public static String GetTicket(String accessToken){
String res = HttpUtils.sendGet(TICKET_URL, "access_token="+accessToken+"&type=jsapi");
Map resObj = JSONObject.fromObject(res);
String ticket = (String) resObj.get("ticket");
return ticket;
}
}
step2: 签名算法 JSSDKUtil.java:
public class WeixinSDKSignUtil {
public static void main(String[] args) {
String jsapi_ticket = "jsapi_ticket";
// 注意 URL 一定要动态获取,不能 hardcode
String url = "http://example.com";
Map ret = sign(jsapi_ticket, url);
};
public static Map sign(String jsapi_ticket, String url) {
Map ret = new HashMap();
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;
try
{
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(string1.getBytes("UTF-8"));
signature = byteToHex(crypt.digest());
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
ret.put("url", url);
ret.put("jsapi_ticket", jsapi_ticket);
ret.put("nonceStr", nonce_str);
ret.put("timestamp", timestamp);
ret.put("signature", signature);
return ret;
}
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;
}
private static String create_nonce_str() {
return UUID.randomUUID().toString();
}
private static String create_timestamp() {
return Long.toString(System.currentTimeMillis() / 1000);
}
}
至此服务器端的签名流程和准备已经全部完成,下期会说整个流程中的前端页面签名步骤