前言:
因為接下來會有幾篇關於微信JS-SDK功能使用的文章,主要會對微信分享,獲取裝置資訊,獲取地理位置,微信掃一掃這幾個功能進行講解。而這幾個功能都是圍繞著微信JS-SDK實現的,首先使用微信JS-SDK時我們需要生成對應的配置資訊,才能夠成功的呼叫微信JS-SDK。看了下微信官方文件對於accessToken和jsapi_ticket的生成示例程式碼並沒有看到我們們大.Net的,所以為了幫助那些剛接觸微信開發的同學,在這裡我會把自己在使用微信JS-SDK的一些步驟和配置資訊生成的方法展示出來,希望能夠和大家相互學習共同進步。
微信JS-SDK詳情說明請移步微信官方文件:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115
JSSDK使用步驟:
步驟一、繫結安全域名:
先登入微信公眾平臺進入“公眾號設定”的“功能設定”裡填寫“JS介面安全域名”。
步驟二、引入JS檔案:
在需要呼叫JS介面的頁面引入如下JS檔案,(支援https):http://res.wx.qq.com/open/js/jweixin-1.4.0.js
專案中:
<script src="http://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
步驟三、通過config介面注入許可權驗證配置:
注意:所有需要使用JS-SDK的頁面必須先注入配置資訊,否則將無法呼叫(同一個url僅需呼叫一次,對於變化url的SPA的web app可在每次url變化時進行呼叫,目前Android微信客戶端不支援pushState的H5新特性,所以使用pushState來實現web app的頁面會導致簽名失敗,此問題會在Android6.2中修復)。
wx.config({ debug: true, // 開啟除錯模式,呼叫的所有api的返回值會在客戶端alert出來,若要檢視傳入的引數,可以在pc端開啟,引數資訊會通過log打出,僅在pc端時才會列印。 appId: '', // 必填,公眾號的唯一標識 timestamp: , // 必填,生成簽名的時間戳 nonceStr: '', // 必填,生成簽名的隨機串 signature: '',// 必填,簽名 jsApiList: [] // 必填,需要使用的JS介面列表,如需要呼叫分享給朋友的話我們填寫為["onMenuShareTimeline"] });
步驟四、通過ready介面處理成功驗證:
注意:假如需要在頁面載入時就呼叫的話,需要把對應的執行函式放到wx.ready(function(){});方法裡面載入執行,之前我呼叫載入就獲取地理位置的介面就是因為沒有放到這裡面所以一直沒有獲取到使用者當前經緯度座標
wx.ready(function(){ // config資訊驗證後會執行ready方法,所有介面呼叫都必須在config介面獲得結果之後,config是一個客戶端的非同步操作,所以如果需要在頁面載入時就呼叫相關介面,則須把相關介面放在ready函式中呼叫來確保正確執行。對於使用者觸發時才呼叫的介面,則可以直接呼叫,不需要放在ready函式中。 });
步驟五、通過error介面處理失敗驗證:
wx.error(function(res){ // config資訊驗證失敗會執行error函式,如簽名過期導致驗證失敗,具體錯誤資訊可以開啟config的debug模式檢視,也可以在返回的res引數中檢視,對於SPA可以在這裡更新簽名。 });
介面呼叫說明請檢視微信開發文件:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115
獲取access_token(公眾號的全域性唯一介面呼叫憑據):
詳細概述:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183
通過介面獲取:
/// <summary> /// 獲取微信公眾號全域性唯一介面憑證 /// </summary> /// <returns></returns> public static string RequestAccessToken() { // 設定引數 string appid =WxAppId;//第三方使用者唯一憑證 string appsecret =WxAppSecret;//第三方使用者唯一憑證金鑰,即appsecret //請求介面獲取 string _url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + appsecret; string method = "GET"; HttpWebRequest request = WebRequest.Create(_url) as HttpWebRequest; CookieContainer cookieContainer = new CookieContainer(); request.CookieContainer = cookieContainer; request.AllowAutoRedirect = true; request.Method = method; request.ContentType = "text/html"; request.Headers.Add("charset", "utf-8"); //傳送請求並獲取相應迴應資料 HttpWebResponse response = request.GetResponse() as HttpWebResponse; //直到request.GetResponse()程式才開始向目標網頁傳送Post請求 Stream responseStream = response.GetResponseStream(); StreamReader sr = new StreamReader(responseStream, Encoding.UTF8); //獲取返回過來的結果 string content = sr.ReadToEnd(); dynamic resultContent=JsonConvert.DeserializeObject(content,new { access_token="", expires_in="", errcode="", errmsg="" }.GetType()); if (resultContent.errcode == "0") //errcode為0時表示請求成功 { return resultContent.access_token;//返回請求唯一憑證 } else { //請求失敗,返回為空 return ""; } }
獲取jsapi_ticket微信公眾號呼叫微信JS介面的臨時票據(前提是:獲取到了公眾號全域性唯一介面呼叫憑據):
/// <summary> /// 獲取jsapi_ticket微信公眾號呼叫微信JS介面的臨時票據 /// </summary> /// <param name="accessToken">微信公眾號的全域性唯一介面呼叫憑證</param> /// <returns></returns> public static string RequestJsapi_ticket(string accessToken) { string content = ""; try { //TODO:注意api_ticket 是用於呼叫微信卡券JS API的臨時票據,有效期為7200 秒,通過access_token 來獲取。 string url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + accessToken + "&type=jsapi"; string method = "GET"; HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; CookieContainer cookieContainer = new CookieContainer(); request.CookieContainer = cookieContainer; request.AllowAutoRedirect = true; request.Method = method; request.ContentType = "text/html"; request.Headers.Add("charset", "utf-8"); //傳送請求並獲取相應迴應資料 HttpWebResponse response = request.GetResponse() as HttpWebResponse; //直到request.GetResponse()程式才開始向目標網頁傳送Post請求 Stream responseStream = response.GetResponseStream(); StreamReader sr = new StreamReader(responseStream, Encoding.UTF8); //獲取返回過來的結果 content = sr.ReadToEnd(); dynamic resultStr = JsonConvert.DeserializeObject(content,new { errcode="", errmsg="",ticket="", expires_in=""}.GetType()); //請求成功 if (resultStr.errcode=="0"&&resultStr.errmsg=="ok") { content=resultStr.ticket; } else { content = ""; } return content; } catch (Exception ex) { content = ex.Message; return content; } }
生成簽名的隨機串(nonceStr):
/// <summary> /// 隨機字串陣列集合 /// </summary> private static readonly string[] NonceStrings = new string[] { "a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z", "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z" }; /// <summary> /// 生成簽名的隨機串 /// </summary> /// <returns></returns> public static string CreateNonceStr() { Random random = new Random(); var sb = new StringBuilder(); var length = NonceStrings.Length; //生成15位數的隨機字串,當然也可以通過控制對應字串大小生成,但是至多不超過32位 for (int i = 0; i < 15; i++) { sb.Append(NonceStrings[random.Next(length - 1)]);//通過random獲得的隨機索引到,NonceStrings陣列中獲取對應陣列值 } return sb.ToString(); }
生成簽名時間戳(timestamp):
/// <summary> /// 獲取當前時間戳 /// </summary> /// <returns></returns> public static long GetCurrentUinxTime() { DateTime currentDate = DateTime.Now;//當前時間 //轉化為時間戳 DateTime localTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); return long.Parse((currentDate - localTime).TotalSeconds.ToString().Split('.')[0]); }
獲取當前網頁URL:
注意:一定要是在安全域名內,否則生成的是無效的簽名。
//獲取當前網頁URL string currentWebUrl = Request.Url.ToString();
生成簽名(signature):
微信JS-SDK使用許可權簽名演算法詳細概述:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115
/// <summary> /// 獲取簽名 /// </summary> /// <param name="jsapi_ticket">微信公眾號呼叫微信JS臨時票據</param> /// <param name="nonceStr">隨機串</param> /// <param name="timestamp">時間戳</param> /// <param name="url">當前網頁URL</param> /// <returns></returns> public static string GetSignature(string jsapi_ticket, string nonceStr, long timestamp, string url) { var string1Builder = new StringBuilder(); //注意這裡引數名必須全部小寫,且必須有序 string1Builder.Append("jsapi_ticket=").Append(jsapi_ticket).Append("&") .Append("noncestr=").Append(nonceStr).Append("&") .Append("timestamp=").Append(timestamp).Append("&") .Append("url=").Append(url.IndexOf("#") >= 0 ? url.Substring(0, url.IndexOf("#")) : url); return Sha1(string1Builder.ToString(),Encoding.UTF8); } /// <summary> /// 簽名加密,使用SHA加密所得 /// </summary> /// <param name="content">簽名加密引數</param> /// <param name="encode">編碼UTF-8</param> /// <returns></returns> public static string Sha1(string content, Encoding encode) { try { SHA1 sha1 = new SHA1CryptoServiceProvider(); byte[] bytesIn = encode.GetBytes(content); byte[] bytesOut = sha1.ComputeHash(bytesIn); sha1.Dispose(); string result = BitConverter.ToString(bytesOut); result = result.Replace("-", ""); return result; } catch (Exception ex) { throw new Exception("SHA1加密出錯:" + ex.Message); } }
總結:
最後要總結一下關於對接第三方的一些心得,有的時候我們在實際專案開發中也許會對接一些我們之前從來都沒有對接過的第三方軟體公司的一些功能比如最為常見的是微信,支付寶,QQ等,在對接之前我們第一步要做的是明確自己的需求,有目的性的去閱讀第三方對接開發文件,因為一般對接文件都是有對應的功能詳細說明,你不可能把所有的文件都看完了再去對接,這樣的話你的專案開發進度肯定是會延期的。學會使用第三方提供的demo示例,因為這將會在很大的程度上幫助你瞭解功能的實現原理。