微信应用开发记录
前端时间在家,朋友介绍开发一个移动应用,即在公众号里面增加一个菜单,然后链接页面通过查询某个银行的附近网点和全部网点。这里有个关键是,在查询附近网点的同时,能够查询出与用户当前的距离,并且能通过百度导航,从当前用户所在地导航到网点。
在这里有两个关键点:
1、如何通过微信的JSSDK,获取当前用户所在的经纬度。
2、如何通过百度地图的API,查询出附近的网点,并获取到网点的经纬度,然后进行导航。
关键点解决方案
1、在微信的JSSDK已经给出相关的API,获取当前用户所在的经纬度。
2、在百度地图的WEBAPI中,也已经给出API,通过查询获取相关数据。
难点和经验
难点1、关于微信JSSDK的验证,微信的验证的难度超过预计,特别是在使用和调试上,经常让人无所适从。
这里吐槽一下:我们看一下JSSDK的说明,简单看一下:
1)、需要引用http://res.wx.qq.com/open/js/jweixin-1.0.0.js
2)、需要配置验证参数:
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: appId, // 必填,公众号的唯一标识
timestamp: timestamp, // 必填,生成签名的时间戳
nonceStr: nonceStr, // 必填,生成签名的随机串
signature: signature,// 必填,签名,见附录1
jsApiList: ['getLocation'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
appId很容易理解,申请的公众号ID。timestamp时间戳怎么来没说,nonceStr签名的随机串怎么生成没说明,signature有说明,通过timestamp、nonceStr、JsapiTicket(7200秒有效)和访问页面Url使用Sha1加密算出signature签名。
微信官方给出PHP的例子,本人使用C#,没用过PHP,还是不知道怎么验证。最后百度了一下,还好已经有人做过了,已经在网上说明。
3)、timestamp产生,(不同语言自己写算法实现,官方有PHP代码)自己写算法实现,生成时间戳 从 1970 年 1 月 1 日 00:00:00 至今的秒数,即当前的时间,且最终需要转换为字符串形式。代码如下:
public static string getTimestamp()
{
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalSeconds).ToString();
}
4)、nonceStr产生,(不同语言自己写算法实现,官方有PHP代码)生成签名的随机串,使用MD5签名结果
public static string getNoncestr()
{
Random random = new Random();
return GetMD5(random.Next(1000).ToString(), "GBK");
}
/** 获取大写的MD5签名结果 */
public static string GetMD5(string encypStr, string charset)
{
string retStr;
MD5CryptoServiceProvider m5 = new MD5CryptoServiceProvider();
//创建md5对象
byte[] inputBye;
byte[] outputBye;
//使用GB2312编码方式把字符串转化为字节数组.
try
{
inputBye = Encoding.GetEncoding(charset).GetBytes(encypStr);
}
catch (Exception ex)
{
inputBye = Encoding.GetEncoding("GB2312").GetBytes(encypStr);
}
outputBye = m5.ComputeHash(inputBye);
retStr = System.BitConverter.ToString(outputBye);
retStr = retStr.Replace("-", "").ToUpper();
return retStr;
}
5)、signature产生,这个复杂了,微信官方真的没说清楚,这里分三步走。
*、首先通过APPID和AppSecret,产生Token票据,通过下面链接获取参数:”https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=” + appid + “&secret=” + secret。(7200秒有效)
*、通过Token票据获取JsapiTicket(7200秒有效),通过下面链接获取参数:https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=” + accesstoken + “&type=jsapi
*、通过timestamp、nonceStr、JsapiTicket(7200秒有效)和访问页面Url使用Sha1加密算出signature签名。这里感谢网上高手,我这里给出参考
http://www.cnblogs.com/ysyn/p/4665897.html,但是Sha1加密,少了一步排序,参考开源组件:
最后代码如下:
/// <summary>
/// 获取JS-SDK权限验证的签名Signature
/// </summary>
/// <param name="ticket"></param>
/// <param name="noncestr"></param>
/// <param name="timestamp"></param>
/// <param name="url"></param>
/// <returns></returns>
public static string GetSignature(string ticket, string noncestr, string timestamp, string url)
{
var parameters = new Hashtable();
parameters.Add("jsapi_ticket", ticket);
parameters.Add("noncestr", noncestr);
parameters.Add("timestamp", timestamp);
parameters.Add("url", url);
return CreateSha1(parameters);
}
/// <summary>
/// sha1加密
/// </summary>
/// <returns></returns>
private static string CreateSha1(Hashtable parameters)
{
var sb = new StringBuilder();
var akeys = new ArrayList(parameters.Keys);
akeys.Sort();
foreach (var k in akeys)
{
if (parameters[k] != null)
{
var v = (string)parameters[k];
if (sb.Length == 0)
{
sb.Append(k + "=" + v);
}
else
{
sb.Append("&" + k + "=" + v);
}
}
}
return getSha1(sb.ToString()).ToString().ToLower();
}
public static String getSha1(String str)
{
//建立SHA1对象
SHA1 sha = new SHA1CryptoServiceProvider();
//将mystr转换成byte[]
ASCIIEncoding enc = new ASCIIEncoding();
byte[] dataToHash = enc.GetBytes(str);
//Hash运算
byte[] dataHashed = sha.ComputeHash(dataToHash);
//将运算结果转换成string
string hash = BitConverter.ToString(dataHashed).Replace("-", "");
return hash;
}
这里有几个关键点,请大家注意,不要走弯路:
*、返回结果的反序列化,可直接用JsonConvert.DeserializeObject实现
*、四个参数大小写不能错,特别是Url的大小写,不能错,这个看网上很多走了弯路,可使用location.href.split('#')[0]
参数的验证地址:有两个要分别验证的(????),为什么微信不一个验证就给人调试验证,让人难以理解。建议微信在增加一个验证调试接口。验证接口http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign,这里验证比较麻烦,通常需要不少时间。
*、innvalid url domain当前页面所在域名与使用的appid没有绑定,请确认正确填写绑定的域名,如果使用了端口号,则配置的绑定域名也要加上端口号,注意按照域名,填写qq.com
难点2、百度地图WebApi的调用,相对来说就简单多了,只需要BaiduKey就行了,可直接使用http://developer.baidu.com/map/index.php?title=webapi。