ASP.NET MVC 微信JS-SDK认证
layout: post
title: ASP.NET MVC 微信JS-SDK认证
category: .net
date: 2016-11-01 00:00:00
tags:
- .net
- javascript
写在前面
前阵子因为有个项目需要做微信自定义分享功能,因而去研究了下微信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...看完之后总结如下:
- 使用config接口注入权限验证配置,重点是生成合法的signatrue
- 生成signature需要通过appid和secret获取token
- 时间戳和调用接口URL必不可少
- 此操作需要服务端完成,不能使用客户端实现
整个过程变成:
通过appid和secret获取access_token,接着使用token获取jsapi_ticket;
拿到jsapi_ticket之后,把jsapi_ticket、时间戳、随机字符串、接口调用页面URL 拼接成完整字符串,使用sha1算法加密得到signature。
最后返回至页面,在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回来继续玩。
PPPPS:成果在这里,SNH48解救行动(流量预警:HTML5游戏,预计获得-15M+流量,非wifi条件祝好运。)。微信打开,直接分享或者完成游戏之后分享都可以看到自定义分享内容。
完整代码:liguobao/WeixinAPI · GitHub(测试前记得把web.config里面的appid和wxsecret改成自己的)
ASP.NET MVC 微信JS-SDK认证的更多相关文章
- 七天学会ASP.NET MVC (四)——用户授权认证问题
小编应各位的要求,快马加鞭,马不停蹄的终于:七天学会 Asp.Net MVC 第四篇出炉,在第四天的学习中,我们主要了学习如何在MVC中如何实现认证授权等问题,本节主要讲了验证错误时的错误值,客户端验 ...
- ASP.NET MVC - 安全、身份认证、角色授权和ASP.NET Identity
ASP.NET MVC - 安全.身份认证.角色授权和ASP.NET Identity ASP.NET MVC内置的认证特性 AuthorizeAttribute特性(System.Web.Mvc)( ...
- 七天学会ASP.NET MVC (四)——用户授权认证问题 【转】
http://www.cnblogs.com/powertoolsteam/p/MVC_four.html 小编应各位的要求,快马加鞭,马不停蹄的终于:七天学会 Asp.Net MVC 第四篇出炉,在 ...
- C#/ASP.NET MVC微信公众号接口开发之从零开发(四) 微信自定义菜单(附源码)
C#/ASP.NET MVC微信接口开发文章目录: 1.C#/ASP.NET MVC微信公众号接口开发之从零开发(一) 接入微信公众平台 2.C#/ASP.NET MVC微信公众号接口开发之从零开发( ...
- C#/ASP.NET MVC微信公众号接口开发之从零开发(三)回复消息 (附源码)
C#/ASP.NET MVC微信接口开发文章目录: 1.C#/ASP.NET MVC微信公众号接口开发之从零开发(一) 接入微信公众平台 2.C#/ASP.NET MVC微信公众号接口开发之从零开发( ...
- ASP.NET MVC 微信公共平台开发之获取用户消息并处理
ASP.NET MVC 微信公共平台开发 获取用户消息并处理 获取用户消息 用户发送的消息是在微信服务器发送的一个HTTP POST请求中包含的,获取用户发送的消息要从POST请求的数据流中获取 微信 ...
- ASP.NET MVC 微信公共平台开发之验证消息的真实性
ASP.NET MVC 微信公共平台开发 验证消息的真实性 在MVC Controller所在项目中添加过滤器,在过滤器中重写 public override void OnActionExecuti ...
- 实战微信JS SDK开发:贺卡制作与播放(1)
前段时间忙于CanTK 2.0的开发,所以博客一直没有更新.CanTK 2.0主要增强了游戏和富媒体的开发,现在编码和测试基本完成了,等文档完成了再正式发布,里面有不少激动人心的功能,等发布时再一一细 ...
- 微信JS SDK接入的几点注意事项
微信JS SDK接入,主要可以先参考官网说明文档,总结起来有几个步骤: 1.绑定域名:先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”.备注:登录后可在“开发者中心”查看对 ...
随机推荐
- ParameterDirection中的参数(Input,Output,InputOutput,ReturnValue)
ParameterDirection中的参数类型定义,首先看ParameterDirection定义 // 摘要: // 指定查询内的有关 System.Data.DataSet 的参数的类型. pu ...
- BZOJ3999:[TJOI2015]旅游(树链剖分)
Description 为了提高智商,ZJY准备去往一个新世界去旅游.这个世界的城市布局像一棵树.每两座城市之间只有一条路径可 以互达.每座城市都有一种宝石,有一定的价格.ZJY为了赚取最高利益,她会 ...
- PHP---练习-----留言板
题目::留言显示 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://ww ...
- 使用@SuppressWarnings("unchecked")消除非受检警告
使用泛型编程时,会遇到许多编译器警告,如:非受检强制转化警告,非受检方法调用警告,非受检普通数组创建警告,费受精转换警告.这次的内容就是遇到这些警告的时候你该怎么办 PS:非受检警告就是代码上黄色的感 ...
- inode的理解
迫于需要理解sock_init()中的init_inodecache,所以稍微学习了一下inode. 一.inode的定义 文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sec ...
- python调用对象属性出错:AttributeError: 'function' object has no attribute '_name_'
出错如下图所示: 原来是因为把__name__写成_name_, 下图为正确结果:
- 工程命名为***&***出现的问题: LaunchScreen.xib: Line 20: EntityRef: expecting ';'
今天新建一个项目命名为28 & 29. extern&static, 然后cmd + R运行,居然碰到了编译错误. 当时就奇怪了,怎么会这样呢?报错内容如下: 开始还以为新安装的Xc ...
- 第24章 QSPI—读写串行FLASH
本章参考资料:<STM32F76xxx参考手册>.<STM32F76xxx规格书>.库帮助文档<STM32F779xx_User_Manual.chm>及<S ...
- 模板——最小生成树prim算法&&向前星理解
通过最小生成树(prim)和最短路径优化引出的向前星存图,时至今日才彻底明白了.. head[i]存储的是父节点为i引出的最后一条边的编号, next负责把head[i]也就是i作为父节点的所有边连接 ...
- 基于MySQL INNODB的优化技巧
背景 回顾人们在开始工作之前,都会问自己这样一个问题:给你一台16G内存的Innodb专用数据库服务器,如何配置才能让其稳定.高效地给典型的Web应用提供服务? 硬件 内存:内存对于Innodb数 ...