ASP.NET MVC 微信JS-SDK认证
asp.net mvc微信js-sdk认证,具体内容:
写在前面
前阵子因为有个项目需要做微信自定义分享功能,因而去研究了下微信js-sdk相关知识。
此文做个简单的记(tu)录(cao)...
开始
所有的东西都从文档开始:微信jssdk说明文档
项目需要用到的是分享接口 不过使用微信js-sdk之前,需要做js接口认证。
认证如下:
步骤一:绑定域名
步骤二:引入js文件
步骤三:通过config接口注入权限验证配置
步骤四:通过ready接口处理成功验证
步骤五:通过error接口处理失败验证
具体解释:
步骤一中允许使用域名/子域名,只要xx.com/xxx.txt或者xx.com/mp/xxx.txt能访问就好。域名认证通过之后,此域名下的所有端口的网站都可以使用js-sdk。
步骤二没什么问题,略过。
步骤三最磨人,下面单独讲解。
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: '',// 必填,签名,见附录1 jsapilist: [] // 必填,需要使用的js接口列表,所有js接口列表见附录2 });
看到这里肯定懵逼了,这是都什么鬼...怎么玩啊。
提示我们去看附录1...看完之后总结如下:
1.使用config接口注入权限验证配置,重点是生成合法的signatrue
2.生成signature需要通过appid和secret获取token
3.时间戳和调用接口url必不可少
4.此操作需要服务端完成,不能使用客户端实现
整个过程变成:
1.通过appid和secret获取access_token,接着使用token获取jsapi_ticket;
2.拿到jsapi_ticket之后,把jsapi_ticket、时间戳、随机字符串、接口调用页面url 拼接成完整字符串,使用sha1算法加密得到signature。
3.最后返回至页面,在wx.config里面填入appid,上一步的时间戳timestamp,上一部的随机字符串、sha1拿到的signature,想要使用的js接口。
废话少说,直接上代码吧。
代码时间
public class weixincontroller : controller { public static readonly string appid = system.web.configuration.webconfigurationmanager.appsettings["wxappid"]; public static readonly string secret = system.web.configuration.webconfigurationmanager.appsettings["wxsecret"]; public static readonly bool isdedug = system.web.configuration.webconfigurationmanager.appsettings["isdebug"] =="true"; public static string _ticket = ""; public static datetime _lasttimestamp; public actionresult info(string url,string noncestr) { if (string.isnullorempty(_ticket) || _lasttimestamp == null || (_lasttimestamp - datetime.now).milliseconds > 7200) { var resultstring = httphelper.gethtmlbyurl("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret); dynamic resultvalue = jsonconvert.deserializeobject<dynamic>(resultstring); if (resultvalue == null || resultvalue.access_token == null || resultvalue.access_token.value == null) { return json(new { issuccess = false, error = "获取token失败" }); } var token = resultvalue.access_token.value; resultstring = httphelper.gethtmlbyurl ("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + token + "&type=jsapi"); dynamic ticketvalue = jsonconvert.deserializeobject<dynamic>(resultstring); if (ticketvalue == null || ticketvalue.errcode == null || ticketvalue.errcode.value != 0 || ticketvalue.ticket == null) return json(new { issuccess = false, error = "获取ticketvalue失败" }); _ticket = ticketvalue.ticket.value; _lasttimestamp = datetime.now; var timestamp = gettimestamp(); var hexstring = string.format("jsapi_ticket={0}&noncestr={3}×tamp={1}&url={2}", _ticket, timestamp, url,noncestr); return json(new { issuccess = true, sha1value = getsha1value(hexstring), timestamp = timestamp, url = url, appid = appid, debug=isdedug, tiket=_ticket }); } else { var timestamp = gettimestamp(); var hexstring = string.format("jsapi_ticket={0}&noncestr=1234567890123456×tamp={1}&url={2}", _ticket, timestamp, url); return json(new { issuccess = true, sha1value = getsha1value(hexstring), timestamp = timestamp, url = url, appid = appid, debug = isdedug,tiket = _ticket }); } } private string getsha1value(string sourcestring) { var hash = sha1.create().computehash(encoding.utf8.getbytes(sourcestring)); return string.join("", hash.select(b => b.tostring("x2")).toarray()); } private static string gettimestamp() { timespan ts = datetime.now - new datetime(1970, 1, 1, 0, 0, 0, 0); return convert.toint64(ts.totalseconds).tostring(); } } public class httphelper { public static string gethtmlbyurl(string url) { string htmlcode = string.empty; try { httpwebrequest webrequest = (system.net.httpwebrequest)system.net.webrequest.create(url); webrequest.timeout = 30000; webrequest.method = "get"; webrequest.useragent = "mozilla/4.0"; webrequest.headers.add("accept-encoding", "gzip, deflate"); httpwebresponse webresponse = (system.net.httpwebresponse)webrequest.getresponse(); //获取目标网站的编码格式 string contentype = webresponse.headers["content-type"]; regex regex = new regex("charset\\s*=\\s*[\\w]?\\s*([\\w-]+)", regexoptions.ignorecase); if (webresponse.contentencoding.tolower() == "gzip")//如果使用了gzip则先解压 { using (system.io.stream streamreceive = webresponse.getresponsestream()) { using (var zipstream = new system.io.compression.gzipstream(streamreceive, system.io.compression.compressionmode.decompress)) { //匹配编码格式 if (regex.ismatch(contentype)) { encoding ending = encoding.getencoding (regex.match(contentype).groups[1].value.trim()); using (streamreader sr = new system.io.streamreader(zipstream, ending)) { htmlcode = sr.readtoend(); } } else { using (streamreader sr = new system.io.streamreader(zipstream, encoding.utf8)) { htmlcode = sr.readtoend(); } } } } } else { using (system.io.stream streamreceive = webresponse.getresponsestream()) { var encoding = encoding.default; if (contentype.contains("utf")) encoding = encoding.utf8; using (system.io.streamreader sr = new system.io.streamreader(streamreceive, encoding)) { htmlcode = sr.readtoend(); } } } return htmlcode; } catch (exception ex) { return ""; } } }
ps:这里要注意缓存一下_ticket(即access_token),照微信文档说的,access_token两个小时内有效,不需要频繁调用。而且获取access_token的接口有调用次数的限制,如果超过了次数,就不允许调用了。
pps:建议noncestr和url由前台传入比较适合,使用 var theweburl = window.location.href.split('#')[0] 获取url,noncestr就随意了。
ppps:遇到诡异的invalid signature的时候,首先检查url参数,然后检查noncestr,再不行重启一下程序获取一个新的token回来继续玩。
本文已被整理到了《asp.net微信开发教程汇总》,欢迎大家学习阅读。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。