前言 之所以写下来也是给自己长记性 我为了搞好微信签名的那个可算是绞尽脑计了
所以写下来一是一点吧
微信 这个文章只是单纯的针对微信开发中的自定义分享的内容的 自定义图片 链接 标题 内容
首先附上官方开发的链接 http://mp.weixin.qq.com/wiki/home/index.html
这个官方专门针对 js_sdk说明 的文档http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html
想开发的 先把这个看上好几遍 弄懂了就按照他的步骤一步步来来这里我默认你签名的基本工作都已经准备好了 直接开始js_sdk
JSSDK使用步骤
步骤一:绑定域名
先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
备注:登录后可在“开发者中心”查看对应的接口权限。
说
明:这里看似乎很简单 我就是被这里坑了的 高能注意 这里的域名只能是一级域名或者一级域名以上的 还必须是icp备案的一级域名
不然没有办法调用微信的接口的 如果你的项目在二级域名下面也可以【前提是这个二级域名是挂靠在你的一级域名下面的 必须是这样 不能乱填 】
步骤二:引入JS文件
在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.0.0.js
备注:支持使用 AMD/CMD 标准模块加载方法加载
说明:这一步是最简单的 直接在你的页面上面引用就可以啦
看下面的就是的
步骤三:通过config接口注入权限验证配置
所
有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的webapp可在每次url变化
时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现webapp的页面会导致签名失败,
此问题会在Android6.2中修复)。
wx.config({ debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名,见附录1 jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2});
说明:你会发现做这个功能这里是耗时最长的 因为他的参数不是一般的复杂
首先 是你的appid 记住这里是你的服务号 必须是服务号 不要写错了 去微信公众平台后台看清楚 你这里写错了很冤枉的 接下来是timestamp 你可以百度一下 生成时间戳的方法很多的 下面贴上我的
///
/// 时间截,自1970年以来的秒数
///
public static string getTimestamp()
{
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalSeconds).ToString();
}
再下来就是nonceStr,这里指的注意的是这里的S必须大写 一定要大写 要按照驼峰原则
最后一个也就是最难的参数
signature
生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况
下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,
频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket 。
参考以下文档获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token):../15/54ce45d8d30b6bf6758f68d2e95bc627.html
用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket):https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
成功返回如下JSON:
{
"errcode":0,
"errmsg":"ok","ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA","expires_in":7200
}
获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了。
签名算法
签名生成规
则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket,timestamp(时间戳),
url(当前网页的URL,不包含#及其后面部分)。对所有待签名参数按照字段名的ASCII码从小到大排序(字典序)后,使用URL键值对的格式(即
key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作
sha1加密,字段名和字段值都采用原始值,不进行URL 转义。
即signature=sha1(string1)。 示例:
noncestr=Wm3WZYTPz0wzccnW
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg
timestamp=1414587457
url=http://mp.weixin.qq.com?params=value
步骤1. 对所有待签名参数按照字段名的ASCII码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1:
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW×tamp=1414587457&url=http://mp.weixin.qq.com?params=value
步骤2. 对string1进行sha1签名,得到signature:0f9de62fce790f9a083d5c99e95740ceb90c27ed
注意事项
签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。
签名用的url必须是调用JS接口页面的完整URL。
出于安全考虑,开发者必须在服务器端实现签名的逻辑。
注
意这里的url参数 是你要交互的页面的全路径 必须是全路径 并且是要去掉#后面的 我实在js写的
所以获取的参数的方式就是encodeURIComponent(location.href.split('#')[0])
然后传到ajax页面接收处理的 string singture
=System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile("jsapi_ticket="+
jstik + "&noncestr=" + nonceStr + "×tamp=" +timeStamp +
"&url=" + url + "", "SHA1");
这个就是最后一个参数了
ps:值得一提的就是你从微
信接口返回的数据格式都是json格式的 所以你要定义相应的类 或者说是model来接收比如这里返回jsapi_ticket 的时候他返回的是{
"errcode":0,
"errmsg":"ok","ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA","expires_in":7200}
所以你定义的就是 ///
/// 获取签名
///
public class Jsapiticket
{
public string errcode { get; set; }
public string errmsg { get; set; }
public string ticket { get; set; }
public string expires_in { get; set; }
}
然后json序列化这里也附上我的方法 ///
///json格式转化
///
///
///
///
public TJsonDeserialize(string jsonString)
{
System.Runtime.Serialization.Json.DataContractJsonSerializer ser
=newSystem.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(T));
System.IO.MemoryStream ms = newSystem.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(jsonString));
T obj = (T)ser.ReadObject(ms);
return obj;
}
好了 参数都得到了 就在ajax页面返回就可以了 我的参数是text类型的
按照他要求的格式把参数写好 记住参数不要写错了 下面按照他的来
步骤四:通过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中的相关接口。
备注:不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回。
以上几个函数都带有一个参数,类型为对象,其中除了每个接口本身返回的数据之外,还有一个通用属性errMsg,其值格式如下:
调用成功时:"xxx:ok" ,其中xxx为调用的接口名
用户取消时:"xxx:cancel",其中xxx为调用的接口名
调用失败时:其值为具体错误信息
基础接口
判断当前客户端版本是否支持指定JS接口
wx.checkJsApi({
jsApiList: ['chooseImage'], // 需要检测的JS接口列表,所有JS接口列表见附录2, success:
function(res) { // 以键值对的形式返回,可用的api值true,不可用为false //
如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"} }});
备注:checkJsApi接口是客户端6.0.2新引入的一个预留接口,第一期开放的接口均可不使用checkJsApi来检测。
分享接口
请注意不要有诱导分享等违规行为,对于诱导分享行为将永久回收公众号接口权限,详细规则请查看:朋友圈管理常见问题 。
获取“分享到朋友圈”按钮点击状态及自定义分享内容接口
wx.onMenuShareTimeline({
title: '', // 分享标题 link: '', // 分享链接 imgUrl: '', // 分享图标 success:
function () { // 用户确认分享后执行的回调函数 }, cancel: function () { //
用户取消分享后执行的回调函数 }});
获取“分享给朋友”按钮点击状态及自定义分享内容接口
wx.onMenuShareAppMessage({
title: '', // 分享标题 desc: '', // 分享描述 link: '', // 分享链接 imgUrl: '', //
分享图标 type: '', // 分享类型,music、video或link,不填默认为link dataUrl: '', //
如果type是music或video,则要提供数据链接,默认为空 success: function () { //
用户确认分享后执行的回调函数 }, cancel: function () { // 用户取消分享后执行的回调函数 }});
获取“分享到QQ”按钮点击状态及自定义分享内容接口
wx.onMenuShareQQ({
title: '', // 分享标题 desc: '', // 分享描述 link: '', // 分享链接 imgUrl: '', //
分享图标 success: function () { // 用户确认分享后执行的回调函数 }, cancel: function () {
// 用户取消分享后执行的回调函数 }});
获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口
wx.onMenuShareWeibo({
title: '', // 分享标题 desc: '', // 分享描述 link: '', // 分享链接 imgUrl: '', //
分享图标 success: function () { // 用户确认分享后执行的回调函数 }, cancel: function () {
// 用户取涀��E5��享后执行的回调函数 }});
获取“分享到QQ空间”按钮点击状态及自定义分享内容接口
wx.onMenuShareQZone({
title: '', // 分享标题 desc: '', // 分享描述 link: '', // 分享链接 imgUrl: '', //
分享图标 success: function () { // 用户确认分享后执行的回调函数 }, cancel: function () {
// 用户取消分享后执行的回调函数 }});
在开发的时候记得在步骤三 把debug设置为true 这样他自己提示你错误 然后要是出错了你就去这里找http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E9.99.84.E5.BD.955-.E5.B8.B8.E8.A7.81.E9.94.99.E8.AF.AF.E5.8F.8A.E8.A7.A3.E5.86.B3.E6.96.B9.E6.B3.95
这里微信开发团队记录了常见的错误 你在这里都可以找到相应的错了
做完了测试没有问题了你就可以把debug改成true了
好了到此为止了