记一次使用微信JS-SDK分享接口,config接口注入权限验证失败, 提示invalid signature签名错误问题的解决办法。
1.开发环境
编程环境:
- Microsoft Visual Studio Enterprise 2019 Version 16.8.0
- 盛派 Senparc.Weixin —— 微信 .NET SDK
- Target framework .Net Framework 4.5
- WebForm与AspNet MVC混合开发
- 花生壳域名与花生壳内网映射,映射本地内网主机与端口(这样就可以在本地Debug了)
微信文档:
-
盛派微信SDK源码地址:https://gitee.com/mirrors/senparc-weixin
-
微信公众号JS-SDK官方文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html
-
JS-SDK使用权限签名算法:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#62
-
JS-SDK常见错误及解决办法:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#66
-
微信JS接口签名校验工具:http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign
签名算法如下图:
2.我的代码
根据微信JS-SDK官方文档和盛派Senparc.Weixin SDK的Demo,我试着进行把一个链接“分享到朋友”或“分享到朋友圈”。
PersonalCenterController中的ShareToWx动作方法如下:
[CheckWxAuthority]
public ActionResult ShareToWx(string id)
{
var vouchersRecord = vouchers.RetrieveVouchersRecord(id);
ViewBag.VouchersRecord = new List<VouchersRecord>() { vouchersRecord };
var appId = HttpContext.Session["AppID"].ToString();
var appSecret = HttpContext.Session["AppSecret"].ToString();
//var jssdkUiPackage = JSSDKHelper.GetJsSdkUiPackage(appId, appSecret, HttpContext.Request.Url.AbsoluteUri);
//return View(jssdkUiPackage);
//获取时间戳
var timestamp = JSSDKHelper.GetTimestamp();
//获取随机码
var nonceStr = JSSDKHelper.GetNoncestr();
string ticket = JsApiTicketContainer.TryGetJsApiTicket(appId, appSecret);
//获取签名
var signature = JSSDKHelper.GetSignature(ticket, nonceStr, timestamp, HttpContext.Request.Url.AbsoluteUri);
ViewData["AppId"] = appId;
ViewData["Timestamp"] = timestamp;
ViewData["NonceStr"] = nonceStr;
ViewData["Signature"] = signature;
return View();
}
ShareToWx动作返回的ShareToWx视图的代码如下:
@*@model Senparc.Weixin.MP.Helpers.JsSdkUiPackage*@
@{
Layout = null;
}
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ShareToWx</title>
<link href="~/plugins/bootstrap-3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="~/plugins/jquery-3.4.1.min.js"></script>
<script src="http://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
<script>
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '@ViewData["AppId"]', // 必填,公众号的唯一标识
timestamp: '@ViewData["Timestamp"]', // 必填,生成签名的时间戳
nonceStr: '@ViewData["NonceStr"]', // 必填,生成签名的随机串
signature: '@ViewData["Signature"]',// 必填,签名
jsApiList: [
'updateAppMessageShareData',
'updateTimelineShareData',
'onMenuShareTimeline',
'onMenuShareAppMessage',
] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2。详见:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#63
});
wx.error(function (res) {
console.log(res);
alert('验证失败');
});
wx.ready(function () {
alert(location.href.split('#')[0]);
var url = 'http://@HttpContext.Current.Request.Url.Host'+':'+'@HttpContext.Current.Request.Url.Port';
alert("url:"+url)
var link = url + '@HttpContext.Current.Request.Url.PathAndQuery';
alert("link:"+link);
var imgUrl = url + '/Image/daijinquanxiaoshoudingdantongji.png';
alert(imgUrl);
//转发到朋友圈
wx.onMenuShareTimeline({
title: 'JSSDK朋友圈转发测试',
link: link,
imgUrl: imgUrl,
success: function () {
alert('转发成功!');
},
cancel: function () {
alert('转发失败!');
}
});
//转发给朋友
wx.onMenuShareAppMessage({
title: 'JSSDK朋友圈转发测试',
desc: '转发给朋友',
link: link,
imgUrl: imgUrl,
type: 'link',
dataUrl: '',
success: function () {
alert('转发成功!');
},
cancel: function () {
alert('转发失败!');
}
});
});
</script>
</head>
<body>
<div class="container">
<ul>
@foreach (var item in ViewBag.VouchersRecord as List<DriverTestMarketWeb.Models.VouchersRecord>)
{
if (item.Vouchers_Type == 0)
{
<li>代金券类别:检测</li>
}
else
{
<li>代金券类别:驾校</li>
}
<li>代金券编号:@item.Vouchers_No</li>
<li>代金券名称:@item.B_content</li>
if (item.Is_SY == 0)
{
<li>代金券状态:未使用</li>
}
else
{
<li>代金券状态:已使用</li>
}
<li>发放日期:@item.Date_FF</li>
<li>金额:@item.Vouchers_Money</li>
}
</ul>
</div>
</body>
</html>
3.问题描述
在Debug调试时,我在ShareToWx动作中得到要进行签名的参数如下:
我发现通过“微信 JS 接口签名校验工具”得到的签名,与调试时得到的signature签名一致!!但微信依然提示我“invalid signature”签名错误!!这究竟是为什么?
4.问题分析
我首先做了如下检查:
- 我反复确认了进行签名的noncestr、jsapi_ticket、timestamp和url参数,都与“微信 JS 接口签名校验工具”中输入的一致,并且两者得到的签名也一致。
- 实际上在 wx.config 接口注入权限验证配置的参数中,也与action动作方法的参数一致。
- 验证action中进行签名的url与view中 wx.updateTimelineShareData 方法的link参数一致。
然后,我蒙了!!!我捋了一下,所有的参数都对呀!怎么提示我“invalid signature”呢?
此时我进行加密的url如下图:
http://www.abc.site:8711/PersonalCenter/ShareToWx/2640
请记住这个URL,正是由于这个URL折磨了我4个小时。。。这是因为我本地IIS部署的网站直接指向了项目根目录,然后调试时不是用的 IIS Express ,而是 Local IIS !!!并且IIS上部署的网站端口为 8711 !!!
5.问题根源
其根源就在于上一步骤定位到的URL,因为它携带了8711端口号,如下:http://www.abc.site:8711/PersonalCenter/ShareToWx/2640
为什么携带了端口号就不行呢?这是由于微信公众号功能设置中的JS接口安全域名配置,不支持IP地址、端口号、和短链域名导致。
6.解决办法
-
将IIS中部署的网站改成80端口
-
将花生壳内网端口改成80
以上。