c# – 使用来自.NET命令行应用程序的已签名Google Maps API地理编码请求

前端之家收集整理的这篇文章主要介绍了c# – 使用来自.NET命令行应用程序的已签名Google Maps API地理编码请求前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
因此,当我导入记录时,我正在编写一个缓存地理编码数据的应用程序.当我使用未签名的请求时,我的工作正常,但是当我尝试使用我公司的clientid和签名时,我似乎无法弄清楚出了什么问题.我总是得到一个403 Forbidden.

这是我的URL构建器:

  1. private const string _googleUri = "http://maps.googleapis.com/maps/api/geocode/xml?address=";
  2. private const string _googleClientId = "XXXXXXXX";
  3. private const string _googleSignature = "XXXXXXXXXXXXXXXXXXXXXXXX";
  4.  
  5. //RESOLVED
  6. private static String GetGeocodeUri(string address)
  7. {
  8. ASCIIEncoding encoding = new ASCIIEncoding();
  9. string url = String.Format("{0}{1}&client={2}&sensor=false",_googleUri,HttpUtility.UrlEncode(address),_googleClientId);
  10.  
  11. // converting key to bytes will throw an exception,need to replace '-' and '_' characters first.
  12. string usablePrivateKey = _googleSignature.Replace("-","+").Replace("_","/");
  13. byte[] privateKeyBytes = Convert.FromBase64String(usablePrivateKey);
  14.  
  15. Uri uri = new Uri(url);
  16. byte[] encodedPathAndQueryBytes = encoding.GetBytes( uri.LocalPath + uri.Query );
  17.  
  18. // compute the hash
  19. HMACSHA1 algorithm = new HMACSHA1(privateKeyBytes);
  20. byte[] hash = algorithm.ComputeHash(encodedPathAndQueryBytes);
  21.  
  22. // convert the bytes to string and make url-safe by replacing '+' and '/' characters
  23. string signature = Convert.ToBase64String(hash).Replace("+","-").Replace("/","_");
  24.  
  25. // Add the signature to the existing URI.
  26. return uri.Scheme + "://" + uri.Host + uri.LocalPath + uri.Query + "&signature=" + signature;
  27.  
  28. }

这是该计划:

  1. public static AddressClass GetResponseAddress(string address)
  2. {
  3. AddressClass GoogleAddress = new AddressClass();
  4. XmlDocument doc = new XmlDocument();
  5. String myUri = GetGeocodeUri(address);
  6.  
  7. try
  8. {
  9. doc.Load(myUri);
  10. XmlNode root = doc.DocumentElement;
  11. if (root.SelectSingleNode("/GeocodeResponse/status").InnerText == "OK")
  12. {
  13. GoogleAddress.Latitude = Double.Parse(root.SelectSingleNode("/GeocodeResponse/result/geometry/location/lat").InnerText);
  14. GoogleAddress.Longitude = Double.Parse(root.SelectSingleNode("/GeocodeResponse/result/geometry/location/lat").InnerText);
  15.  
  16. }
  17. }
  18. catch (Exception ex)
  19. {
  20. Console.WriteLine("Exception <" + ex.Message + ">");
  21.  
  22. }
  23.  
  24. return GoogleAddress;
  25. }

现在,我对它不起作用的最初反应是Google必须错过引用域,因为它们必须注册.所以我尝试使用HttpWebRequest并将引用设置为我的域,但仍然没有骰子.

  1. //Not needed,Just an alternate method
  2. public static AddressClass GetResponseAddress(string address)
  3. {
  4. AddressClass GoogleAddress = new AddressClass();
  5. WebClient client = new WebClient();
  6. XmlDocument doc = new XmlDocument();
  7. Uri myUri = new Uri(GetGeocodeUri(address));
  8. HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(myUri);
  9. myRequest.Referer = "http://www.myDomain.com/";
  10.  
  11. //I've even tried pretending to be Chrome
  12. //myRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.7 (KHTML,like Gecko) Chrome/16.0.912.75 Safari/535.7";
  13.  
  14. try
  15. {
  16. doc.Load(myRequest.GetResponse().GetResponseStream());
  17. XmlNode root = doc.DocumentElement;
  18. if (root.SelectSingleNode("/GeocodeResponse/status").InnerText == "OK")
  19. {
  20. GoogleAddress.Latitude = Double.Parse(root.SelectSingleNode("/GeocodeResponse/result/geometry/location/lat").InnerText);
  21. GoogleAddress.Longitude = Double.Parse(root.SelectSingleNode("/GeocodeResponse/result/geometry/location/lat").InnerText);
  22. }
  23. }
  24. catch (Exception ex)
  25. {
  26. Console.WriteLine("Exception <" + ex.Message + ">");
  27.  
  28. }
  29.  
  30. return GoogleAddress;
  31. }

任何帮助将非常感激.

解决方法

有时需要URL编码(见下文),但还不够.您的问题是,事实上,您并未签署您的请求.

您的_googleSignature常量中的值不是签名,而是您的私有加密密钥,这很糟糕.您的私人加密密钥永远不应该成为任何请求的一部分.

相反,您需要使用它为每个唯一请求生成新签名.请参阅Maps API for Business Authentication文档,它还包括Signing a URL in Java的示例:)

使用Maps API for Business客户端ID和您的私人加密密钥对Google Maps API Web服务的请求进行签名时,Referer标头和源IP地址完全无关;)

URL编码仅在地址参数上是必需的,作为Building a Valid URL的一部分.您不应对您的签名进行URL编码,因为它已经是URL安全的,使用修改后的Base64 for URL.

猜你在找的C#相关文章