微信簽名算法的服務端實現(.net版本)


一、概要

微信此次開放JS接口,開放了一大批api權限,即使在未認證的訂閱號也可以使用圖像接口,音頻接口,智能接口,地理位置,界面操作,微信掃一掃等功能。要知道:以前訂閱號只能接受和被動回復用戶消息而已。微信官方沒有給出.net版本,有java,node,php和python,唯獨沒有.net版本,這是怎么了?本文就教你實現.net版本的微信JS-SDK權限簽名生成算法。


這會大大激發了js前端開發人員的熱情,可以做更多的事情,不用在向以前一樣用破解微信的weixinbridge狼狽的苟活於人世了。
我認為在這個js橫行霸道的世界,微信早就應該這么做了。當年就是因為沒有js的接口,在微信中無法獲取用戶的分享,導致用戶體驗極差,現在這個問題都解決了。

但那是唯一的缺憾是沒有完全開發分享接口,對於未認證的訂閱號來說還是有些許不便。
不過從微信最近啟用的原創申明功能來說,對於未認證的公眾號來說,若是開放了分享接口,是無法保護原創申明的。
如果您想使用分享,就趕快認證吧。

 防止盜鏈,原文地址:www.cnblogs.com/deepleo/p/weixinjssdk.html

二、業務邏輯

公眾號在調用JS接口之前需要生成JS-SDK使用權限簽名,這部分邏輯需要用戶自己在服務端實現,比較不靠譜的是微信官方沒有給出.net版本的demo.

有java,node,php和python,唯獨沒有.net版本,你沒有看錯。

好吧既然如此我們就自己實現了。

 

生成方法如下(一下摘自微信官方文檔)

附錄1-JS-SDK使用權限簽名算法

jsapi_ticket

生成簽名之前必須先了解一下jsapi_ticket,jsapi_ticket是公眾號用於調用微信JS接口的臨時票據。正常情況下,jsapi_ticket的有效期為7200秒,通過access_token來獲取。由於獲取jsapi_ticket的api調用次數非常有限,頻繁刷新jsapi_ticket會導致api調用受限,影響自身業務,開發者必須在自己的服務全局緩存jsapi_ticket 。

  1. 參考以下文檔獲取access_token(有效期7200秒,開發者必須在自己的服務全局緩存access_token):../15/54ce45d8d30b6bf6758f68d2e95bc627.html
  2. 用第一步拿到的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&timestamp=1414587457&url=http://mp.weixin.qq.com?params=value


步驟2. 對string1進行sha1簽名,得到signature:

0f9de62fce790f9a083d5c99e95740ceb90c27ed

注意事項

  1. 簽名用的noncestr和timestamp必須與wx.config中的nonceStr和timestamp相同。
  2. 簽名用的url必須是調用JS接口頁面的完整URL。
  3. 出於安全考慮,開發者必須在服務器端實現簽名的邏輯。

三、代碼實現

1.獲取jsapi_ticket

復制代碼
// <summary>
        /// 獲取jsapi_ticket
        /// jsapi_ticket是公眾號用於調用微信JS接口的臨時票據。
        /// 正常情況下,jsapi_ticket的有效期為7200秒,通過access_token來獲取。
        /// 由於獲取jsapi_ticket的api調用次數非常有限,頻繁刷新jsapi_ticket會導致api調用受限,影響自身業務,開發者必須在自己的服務全局緩存jsapi_ticket 。
///本代碼來自開源微信SDK項目:https://github.com/night-king/weixinSDK /// </summary> /// <param name="access_token">BasicAPI獲取的access_token,也可以通過TokenHelper獲取</param> /// <returns></returns> public static dynamic GetTickect(string access_token) { var url = string.Format("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type=jsapi", access_token); var client = new HttpClient(); var result = client.GetAsync(url).Result; if (!result.IsSuccessStatusCode) return string.Empty; var jsTicket = DynamicJson.Parse(result.Content.ReadAsStringAsync().Result); return jsTicket; }
復制代碼

 

2.簽名算法

簽名之前我們需要解決隨機字符串和時間戳的問題,

2.1隨機字符串生成算法

復制代碼
  private static string[] strs = 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>
        /// 創建隨機字符串
///本代碼來自開源微信SDK項目:https://github.com/night-king/weixinSDK /// </summary> /// <returns></returns> public static string CreatenNonce_str() { Random r = new Random(); var sb = new StringBuilder(); var length = strs.Length; for (int i = 0; i < 15; i++) { sb.Append(strs[r.Next(length - 1)]); } return sb.ToString(); }
復制代碼

2.2 時間戳

時間戳的參考了這個:http://tool.chinaz.com/Tools/unixtime.aspx

復制代碼
/// <summary>
        /// 創建時間戳
///本代碼來自開源微信SDK項目:https://github.com/night-king/weixinSDK /// </summary> /// <returns></returns> public static long CreatenTimestamp() { return (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000; }
復制代碼

2.3 簽名算法如下:

復制代碼
/// <summary>
        /// 簽名算法
///本代碼來自開源微信SDK項目:https://github.com/night-king/weixinSDK /// </summary> /// <param name="jsapi_ticket">jsapi_ticket</param> /// <param name="noncestr">隨機字符串(必須與wx.config中的nonceStr相同)</param> /// <param name="timestamp">時間戳(必須與wx.config中的timestamp相同)</param> /// <param name="url">當前網頁的URL,不包含#及其后面部分(必須是調用JS接口頁面的完整URL)</param> /// <returns></returns> public static string GetSignature(string jsapi_ticket, string noncestr, long timestamp, string url, out string string1) { 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); string1 = string1Builder.ToString(); return Util.Sha1(string1); }
復制代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM