微信公众号自定义分享功能
一.测试微信公众号接入自己的系统
写个后台接入的方法
[HttpGet]
public string Validate(string signature,string timestamp,string nonce,string echostr)
{
//1. 将token、timestamp、nonce三个参数进行字典序排序
string[] arr = {timestamp, nonce, WeChatUtil.Token};
Array.Sort(arr);
//2. 将三个参数字符串拼接成一个字符串进行sha1加密
StringBuilder sb = new StringBuilder();
foreach (var temp in arr)
{
sb.Append(temp);
}
string sha1 = EncryptionSha1.EncryptString(sb.ToString()).ToLower();
if (sha1.Equals(signature))
{
//接入成功
Trace.WriteLine("接入成功");
return echostr;
}
//接入失败
return null;
}
注意:
1.这个方法必须是get请求
2.微信调用这个方法会自动传入四个参数
3.通过token(公众号配置中的token),和传入的timestamp,nonce三个参数,字典排序,然后sha1加密
4.加密结果就应该等于微信传入的第一个signature参数
5.判断加密结果和signature,如果相同,表示接入成功,将微信传入的第四个参数源样返回.如果不同,返回null,就表示接入失败
然后将这个方法地址填写到微信接入配置的URL中,和用到token也配置进去
二.使用微信JS-SDK
JSSDK中的wx.config需要几个参数,需要后台返回给它,
[HttpGet]
public void GetSignature(string url,string callback)
{
var appid = WeChatUtil.AppId;
var timeStamp = WeChatUtil.GetTimeStamp();
var nonceStr = WeChatUtil.GetNonceStr();
var signature = WeChatUtil.GetSignature(timeStamp, nonceStr, url);
var obj = JsonConvert.SerializeObject(new {appid = appid, timeStamp = timeStamp , nonceStr = nonceStr, signature= signature });
var jsonp = $"{callback}({obj})";
HttpContext.Response.ContentType= "application/json";
HttpContext.Response.Write(jsonp);
}
1,返回appid.
2.返回timestamp,这个就是后台生成个时间戳就行
3.返回nonceStr,随便生成一个随机字符串就可以
4.返回签名signature 比较复杂,看下面代码
public static string GetSignature(string timestamp,string nonceStr,string url)
{
string str =
$"jsapi_ticket={GetJsApiTicket()}" +
$"&noncestr={nonceStr}" +
$"×tamp={timestamp}" +
$"&url={url}";
return EncryptionSha1.EncryptStringSha1(str).ToLower();
}
public static string GetJsApiTicket()
{
string ticket;
ICacheManager cache = new MemoryCacheManager();
var contains = cache.Contains("js_api_ticket");
if (contains)
{
ticket =cache.GetCache<string>("js_api_ticket");
}
else
{
var httpGet = HttpHelper.HttpGet(GetTicketUrl(), "");
var jsApiTicketModel = JsonConvert.DeserializeObject<JsApiTicketModel>(httpGet);
if (jsApiTicketModel.errcode == 0)
{
ticket = jsApiTicketModel.ticket;
long expiresIn = jsApiTicketModel.expires_in;
cache.SetCache("js_api_ticket", ticket,TimeSpan.FromSeconds(expiresIn-60));
}
else
{
ticket = null;
}
}
// var httpGet = HttpHelper.HttpGet(GetTicketUrl(), "");
// var jsApiTicketModel = JsonConvert.DeserializeObject<JsApiTicketModel>(httpGet);
// ticket = jsApiTicketModel.errcode == 0 ? jsApiTicketModel.ticket : null;
return ticket;
}
private static string GetTicketUrl()
{
string url = $"https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={GetAccessToken()}&type=jsapi";
return url;
}
public static string GetAccessToken()
{
string accessToken;
ICacheManager cache = new MemoryCacheManager();
var contains = cache.Contains("access_token");
if (contains)
{
accessToken = cache.GetCache<string>("access_token");
}
else
{
var result = HttpHelper.HttpGet(GetAccessTokenUrl(), "");
var accessTokenModel = JsonConvert.DeserializeObject<AccessTokenModel>(result);
accessToken = accessTokenModel.access_token;
long expiresIn = accessTokenModel.expires_in;
cache.SetCache("access_token", accessToken,TimeSpan.FromSeconds(expiresIn-60));
}
return accessToken;
}
说明,顺序就是生成签名 --> 依赖JsApiTicket--->依赖TickertUrl --> GetAccessToken
然后将这四个值传给wx.config
三,前端JS
var secure_domain='http://www.taekwondoshow.com';//微信js SDK安全域名
var url_str = window.location.href;
var wx_baseUrl='http://q6m89n.natappfree.cc/';
/**
* 全局分享调用
*/
$(function(){
get_signature();
})
function get_signature() {
$.ajax({
type: "GET",
url: wx_baseUrl + "/Wechat/Login_Service/_wxSign?jsoncallback=?",
data: { url: url_str },
cache: false,
dataType: "jsonp",
success: function (data) {
var result = eval('(' + data + ')');
if(result.code ==200){
try{
wx_config(result.data.appid, result.data.timestamp, result.data.noncestr, result.data.sign);
}catch(e){
console.log(e);
}
}
},
error: function () {
console.log("配置参数错误!");
}
});
}
function wx_config(appid, timestamp, nonceStr, signature) {
//通过config接口注入权限验证配置
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: appid, // 必填,公众号的唯一标识
timestamp: timestamp, // 必填,生成签名的时间戳
nonceStr: nonceStr, // 必填,生成签名的随机串
signature: signature, // 必填,签名
jsApiList: ['onMenuShareAppMessage', 'onMenuShareTimeline','hideMenuItems'] // 必填,需要使用的JS接口列表
});
}
wx.ready(function () {
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
wx.onMenuShareAppMessage({
title: '自定义标题', // 分享标题
desc: '自定义描述', // 分享描述
link: secure_domain+'/error401.html', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: secure_domain+'/asset/images/erweima.png', // 分享图标
success: function () {
// 设置成功
}
});
wx.onMenuShareTimeline({
title: '朋友圈标题', // 分享标题
link: secure_domain+'/error401.html', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: secure_domain+'/asset/images/erweima.png', // 分享图标
success: function () {
// 设置成功
}
});
wx.hideMenuItems({
menuList:[ "menuItem:share:qq",
"menuItem:share:weiboApp",
"menuItem:favorite",
"menuItem:share:facebook",
"menuItem:share:QZone",
"menuItem:editTag",
"menuItem:delete",
"menuItem:copyUrl",
"menuItem:originPage",
"menuItem:openWithQQBrowser",
"menuItem:openWithSafari",
"menuItem:share:email",
"menuItem:share:brand"
]
})
});
注意:坑1--分享接口中的link和imgurl必须是微信配置中的JS安全域名下的网址
坑2 ---文档说'onMenuShareAppMessage', 'onMenuShareTimeline'这两个接口即将作废,让用两个新的
但新的有很多问题,IOS可以分享,安卓不行
记录下我参考的教程
https://www.jianshu.com/p/443c905e58a3
https://www.jianshu.com/p/b3c4450f845e


浙公网安备 33010602011771号