微信签名算法的服务端实现(.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);
        }

时间: 2024-12-24 09:35:46

微信签名算法的服务端实现(.net版本)的相关文章

微信JS-SDK使用权限签名算法的服务端实现(.net版本)

一.概要 微信此次开放JS接口,开放了一大批api权限,即使在未认证的订阅号也可以使用图像接口,音频接口,智能接口,地理位置,界面操作,微信扫一扫等功能.要知道:以前订阅号只能接受和被动回复用户消息而已.微信官方没有给出.net版本,有java,node,php和python,唯独没有.net版本,这是怎么了?本文就教你实现.net版本的微信JS-SDK权限签名生成算法. 这会大大激发了js前端开发人员的热情,可以做更多的事情,不用在向以前一样用破解微信的weixinbridge狼狈的苟活于人世

微信开发SDK|微信sdk使用教程--手机客户端微信下线通知服务端

微信开发SDK|微信sdk使用教程--手机客户端微信下线通知服务端 case WeChatOfflineNotice: {// 手机客户端微信下线通知 log.debug("socket:msgtype=WeChatOfflineNotice"); weChatOfflineNoticeHandler.handleMsg(ctx, msgVo); break; } package com.jubotech.framework.netty.handler.socket; import o

纯正商业级应用-Node.js Koa2开发微信小程序服务端

第1章 前言.导学与node.js如何理解Node.js?前端到底要不要学习Node.js?本课程能让你学到什么? 第2章 Koa2的那点事儿与异步编程模型Koa非常的精简,基本上,没有经过二次开发的Koa根本“不能”用.本章我们讲解Koa的重要特性,理解什么是洋葱模型?以及在KOA中如何进行异步编程?很多同学都了解以上知识点,但听完本章,你会有一些不一样的理解,比如:为什么要有洋葱模型?没有会怎样?Koa中间件一定是异步的吗? ... 第3章 路由系统的改造Koa-router需要进行一些改造

微信APP支付服务端开发Java版(一)

一.准备工作 去微信开发者中心下载(扫码支付,里面的大部分代码是可以用的) https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=11_1 选择UTF-8的版本copy到你的项目里面 找到Configure.java的类修改成public static String PAY_API = "https://api.mch.weixin.qq.com/pay/unifiedorder"; 下面正式进入代码部分 1 //初始化

微信绑定用户服务端代码-根据code获取openId然后绑定用户

目录结构: isa.qa.core.weixin.message.resp包和isa.qa.core.weixin.util包中为微信绑定的工具类,就不一一贴出代码,详见附件,下载地址: http://files.cnblogs.com/files/007sx/weixin_util.zip jar包(包括了微信支付所需jar此处一起列出)  pom.xml <!-- weixin --> <dependency> <groupId>com.ning</group

服务端兼容多个不同APP版本

1.实现目标 发布第N版APP,不影响N版本之前APP的正常使用,不强制用户升级APP版本,兼容多个版本的APP的正常使用. 2.解决思路 服务端维护不同版本APP的api(例如版本参数 v1.v2.v3-),根据手机端传递的URL及版本信息,动态调用对应的api. 3.常见的方案 3.1 常见的URL请求传递版本信息的4中方式 url+版本参数: www.xxx.com/api.xxx?version=v1 www.xxx.com/sys/user/getUserByName?version=

zabbix (一:zabbix服务端)

默认情况下zabbix有5个进程: zabbix_agent  zabbix_get zabbix_proxy zabbix_sender zabbix_server,另外一个zabbix_java_gateway是可选,这个需要另外安装. zabbix_agentd:客户端守护进程,此进程收集客户端数据,例如cpu负载.内存.硬盘使用情况等 zabbix_get:zabbix工具,单独使用的命令,通常在server或者proxy端执行获取远程客户端信息的命令.通常用户排错.例如在server端

七牛云存储android客户端及java服务端代码编写

前一篇博客提到让我很伤心的c应用,由于是一款供用户上传图片的应用,因此必须解决图片存储问题,如果直接将图片存储至服务器,当用户上传图片较多,服务器空间将很快吃紧,同时也没有那么大的带宽,现实中我买的阿里云服务器是最低配置,数据盘才20G,带宽才1M,如果用这样配置的服务器做图片存储,那实在太扯了.于是很自然的想到用图片云存储服务器,通过不断查找资料,最后将目标定位在七牛云和又拍云.在做选择时,主要对比了两者之间的价格及技术优势,也看了很多相关话题讨论,个人认为这两者无论从技术方案还是产品价格,都

webservice -- cxf客户端调用axis2服务端

背景: 有个项目, 需要由第三方提供用户信息, 实现用户同步操作, 对方给提供webservice接口(axis2实现)并也使用axis2作主客户端调用我方提供的webservice接口 起初, 由于项目使用了spring, 且spring可与cxf较好的集成, 所以也就选用了cxf, 可问题随之出现, 接口可以调用到, 接口的具体方法也可以调用到, 但是, 1. cxf作为客户端, 获取服务端返回值时均为null. 2. cxf作为服务端, 获取axis2客户端传来的参数时, 也均为null.