1.绑定域名
去微信公众号平台中设置js接口安全域名,要注意的是不填写http://, 只填写域名即可,如 www.baidu.com。
一个月只能修改三次,要谨慎填写。
2.引入JS文件
在页面中引入微信js脚本文件。 <script src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
3.写入config文件配置
1 wx.config({ 2 debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 3 appId: '', // 必填,公众号的唯一标识 4 timestamp:,// 必填,后台生成的时间戳 5 nonceStr: '',//必填,后台生成的随机字符串 6 signature: '',//必填,后台根据token,ticket,时间戳,和随机字符串生成签名 7 jsApiList: [ 8 'checkJsApi', 9 'onMenuShareTimeline', 10 'onMenuShareAppMessage', 11 'onMenuShareQQ', 12 'onMenuShareWeibo', 13 'onMenuShareQZone', 14 'hideMenuItems', 15 'showMenuItems', 16 'hideAllNonBaseMenuItem', 17 'showAllNonBaseMenuItem', 18 'translateVoice', 19 'startRecord', 20 'stopRecord', 21 'onVoiceRecordEnd', 22 'playVoice', 23 'onVoicePlayEnd', 24 'pauseVoice', 25 'stopVoice', 26 'uploadVoice', 27 'downloadVoice', 28 'chooseImage', 29 'previewImage', 30 'uploadImage', 31 'downloadImage', 32 'getNetworkType', 33 'openLocation', 34 'getLocation', 35 'hideOptionMenu', 36 'showOptionMenu', 37 'closeWindow', 38 'scanQRCode', 39 'chooseWXPay', 40 'openProductSpecificView', 41 'addCard', 42 'chooseCard', 43 'openCard' 44 ] 45 });
4.调用接口
(1)首先要知道微信给你生成的AppID和AppSecret,
(2)根据AppId和AppSecret到https://api.weixin.qq.com/cgi-bin/token获取AccessToken。
access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token)
(3)然后拿着Token到https://api.weixin.qq.com/cgi-bin/ticket/getticket获取ticket。
用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket)
(4)然后根据ticket和随机字符串和时间戳和当前页面的url生成Signature(签名)。
签名算法:签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。
(a){对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。
(b)对string1进行sha1签名,得到signature.
1 public static class WeHelper 2 { 3 public static string appId 4 { 5 get 6 { 7 return "";//微信开发者appId 8 } 9 } 10 private static string secret 11 { 12 get 13 { 14 return "";//微信开发者secret 15 } 16 } 17 18 private static readonly string tokenUrl = "https://api.weixin.qq.com/cgi-bin/token"; 19 20 private static readonly string ticket = "https://api.weixin.qq.com/cgi-bin/ticket/getticket"; 21 22 /// <summary> 23 /// 获取Token 24 /// </summary> 25 /// <returns></returns> 26 public static string GetAccessToken() 27 { 28 if (HttpRuntime.Cache.Get("AccessToken") == null) 29 { 30 StringBuilder sbUrl = new StringBuilder(); 31 sbUrl.AppendFormat(tokenUrl); 32 sbUrl.AppendFormat("?grant_type=client_credential"); 33 sbUrl.AppendFormat("&appid={0}", appId); 34 sbUrl.AppendFormat("&secret={0}", secret); 35 using (WebClient client = new WebClient()) 36 { 37 client.Encoding = Encoding.UTF8; 38 string data = client.UploadString(sbUrl.ToString(), string.Empty); 39 var result = JObject.Parse(data); 40 if (result["access_token"] != null && result["access_token"].Value<string>() != string.Empty) 41 { 42 string token = result["access_token"].Value<string>(); 43 HttpRuntime.Cache.Insert("AccessToken", token, null, DateTime.Now.AddSeconds(7200), System.Web.Caching.Cache.NoSlidingExpiration); 44 return token; 45 } 46 else 47 throw new Exception(data); 48 } 49 } 50 else 51 { 52 return HttpRuntime.Cache.Get("AccessToken").ToString(); 53 } 54 } 55 /// <summary> 56 /// 获取token 57 /// </summary> 58 /// <param name="accessToken"></param> 59 /// <returns></returns> 60 public static string GetTicket(string accessToken) 61 { 62 if (HttpRuntime.Cache.Get("Ticket") == null) 63 { 64 StringBuilder sbUrl = new StringBuilder(); 65 sbUrl.AppendFormat(ticket); 66 sbUrl.AppendFormat("?access_token={0}", accessToken); 67 sbUrl.AppendFormat("&type=jsapi"); 68 using (WebClient client = new WebClient()) 69 { 70 client.Encoding = Encoding.UTF8; 71 string data = client.UploadString(sbUrl.ToString(), string.Empty); 72 var result = JObject.Parse(data); 73 if (result["ticket"] != null && result["ticket"].Value<string>() != string.Empty) 74 { 75 string ticket = result["ticket"].Value<string>(); 76 HttpRuntime.Cache.Insert("Ticket", ticket, null, DateTime.Now.AddSeconds(7200), System.Web.Caching.Cache.NoSlidingExpiration); 77 return ticket; 78 } 79 else 80 throw new Exception(data); 81 } 82 } 83 else 84 { 85 return HttpRuntime.Cache.Get("Ticket").ToString(); 86 } 87 } 88 /// <summary> 89 /// 获取签名 90 /// </summary> 91 /// <param name="timestamp"></param> 92 /// <param name="noncestr"></param> 93 /// <param name="url"></param> 94 /// <returns></returns> 95 public static string GetSignature(string timestamp,string noncestr,string url) 96 { 97 string string1 = "jsapi_ticket=" + GetTicket(GetAccessToken()) + "&noncestr=" + noncestr + "×tamp=" + timestamp + "&url=" + url; 98 //使用sha1加密这个字符串 99 return SHA1(string1); 100 } 101 #region 工具类 102 /// <summary> 103 /// 生成随机字符串 104 /// </summary> 105 /// <returns></returns> 106 public static string CreateNonceStr() 107 { 108 int length = 16; 109 string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; 110 string str = ""; 111 var rad = new Random(); 112 for (int i = 0; i < length; i++) 113 { 114 str += chars.Substring(rad.Next(0, chars.Length - 1), 1); 115 } 116 return str; 117 } 118 119 /// <summary> 120 /// 加密 121 /// </summary> 122 /// <param name="str"></param> 123 /// <returns></returns> 124 public static string SHA1(string str) 125 { 126 str = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, "SHA1").ToString(); 127 return str.ToLower(); 128 } 129 130 /// <summary> 131 /// 生成时间戳 132 /// </summary> 133 /// <returns></returns> 134 public static string CreateTimestamp() 135 { 136 TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0); 137 string timestamp = Convert.ToInt64(ts.TotalSeconds).ToString(); 138 return timestamp; 139 } 140 #endregion 141 }
1 /// <summary> 2 /// 获取微信信息 3 /// </summary> 4 /// <returns></returns> 5 public ActionResult GetWeInfo() 6 { 7 string timpstamp = WeHelper.CreateTimestamp(); 8 string nonceStr = WeHelper.CreateNonceStr(); 9 string url = Request.Url.ToString(); 10 string sig = WeHelper.GetSignature(timpstamp, nonceStr, url); 11 12 return Json(new 13 { 14 appId= WeHelper.appId, 15 timpstamp = timpstamp, 16 noncestr = nonceStr, 17 signature = WeHelper.SHA1(sig) 18 }); 19 }
5前台页面
首先要将微信的config信息写入。可以ajax调用。或者后台输出到前台。这里使用ajax调用。
1 $(function () { 2 $.ajax({ 3 type: "post", 4 dataType: "json", 5 url: "/Home/GetWeInfo", 6 success: function (data) { 7 wx.config({ 8 debug: false, 9 appId: data.appId,//微信开发者appId 10 timestamp: data.timestamp,//后台生成的时间戳 11 nonceStr: data.noncestr,//随机字符串 12 signature: data.signature,//后台生成的签名 13 jsApiList: ['checkJsApi', 'scanQRCode']//要调用的微信接口 14 }); 15 } 16 }); 17 });
1 <a class="btn btn-default" onclick="scan()">点击扫一扫</a> 2 3 function scan() { 4 wx.scanQRCode({ 5 needResult: 1, 6 scanType: ["qrCode"], 7 desc: 'scanQRCode desc', 8 success: function (res) { 9 alert(JSON.stringify(res));//这里可以获取到扫描得到的内容。 10 } 11 }); 12 }
备注:
要注意的是token与ticketd在微信端都有7200秒的缓存。并且第一步的URL和第四部的URL都要按照微信要求的格式填写,不要写成局域网的地址。
在微信端调试非常费劲,因为每次都要发布到正式环境。
建议后台多用日志,前台多用log输出或者alert输出,也可以使用微信开发者工具。
如果一切都配置成功的话,返回结果如下: