用于签署Flickr API请求的无效签名(在控制台中进行模拟)

我正在尝试对Flickr API进行身份validation,以获取我想为自己制作的演示应用程序。 然后我将使用我将学习Flick API的新function扩展此应用程序。

所以这只是我想要玩的东西。 但是现在我在获取请求令牌方面遇到了一些麻烦。

我在这里关注Flickr身份validation文档: Flickr身份validation
我还发现了这个Mathlabscript: Flickr API和基于OAuth的用户身份validation

所以基于这些来源我现在有以下控制台应用程序:

class Program { private static string Secret = "2b2b2b2b2b2b2b2b2b"; private static string ConsumerKey = "1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a"; static void Main(string[] args) { Random rand = new Random(); string nonce = rand.Next(9999999).ToString(); string timestamp = ((int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds).ToString(); Console.WriteLine("Nonce: " + nonce); Console.WriteLine("TimeStamp: " + timestamp); Console.WriteLine("ConsumerKey: " + ConsumerKey); Console.WriteLine("AppSecret: " + Secret); //request url StringBuilder b = new StringBuilder(); b.Append("http://www.flickr.com/services/oauth/request_token"); b.Append("?"); b.Append("oauth_nonce="); b.Append(nonce); b.Append("&oauth_timestamp="); b.Append(timestamp); b.Append("&oauth_consumer_key="); b.Append(ConsumerKey); b.Append("&oauth_callback=oob"); b.Append("&oauth_signature_method=HMAC-SHA1"); string requesturl = b.ToString(); Console.WriteLine("RequestUrl: " + requesturl); //base url string basestring; StringBuilder bs = new StringBuilder(); bs.Append("GET&"); bs.Append(UrlHelper.Encode("http://www.flickr.com/services/oauth/request_token")+"&"); basestring = bs.ToString(); StringBuilder p = new StringBuilder(); p.Append("oauth_callback=oob"); p.Append("&oauth_consumer_key="); p.Append(ConsumerKey); p.Append("oauth_nonce="); p.Append(nonce); p.Append("&oauth_signature_method=HMAC-SHA1"); p.Append("&oauth_timestamp="); p.Append(timestamp); string paramers = UrlHelper.Encode(p.ToString()); basestring += paramers; Console.WriteLine("Basestring: " + basestring); System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); string key = Secret + "&"; Console.WriteLine("Key: " + key); byte[] keyByte = encoding.GetBytes(key); //--create message to encrypt byte[] messageBytes = encoding.GetBytes(basestring); //--encrypt message using hmac-sha1 with the provided key HMACSHA1 hmacsha1 = new HMACSHA1(keyByte); byte[] hashmessage = hmacsha1.ComputeHash(messageBytes); //--signature string signature = ByteToString(hashmessage); Console.WriteLine("Signature: " + signature); Console.WriteLine("Final Request: " + requesturl + "&oauth_signature=" + signature); Console.ReadKey(true); } public static string ByteToString(byte[] buff) { string sbinary = ""; for (int i = 0; i < buff.Length; i++) { sbinary += buff[i].ToString("X2"); // hex format } return (sbinary); } } 

当我浏览这个应用程序给我的URL时,我收到以下响应:

 oauth_problem=signature_invalid&debug_sbs=GET&http%3A%2F%2Fwww.flickr.com%2Fservices%2Foauth%2Frequest_token&oauth_callback%3Dhttp%253A%252F%252Fwww.google.be%26oauth_consumer_key%3D1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a%26oauth_nonce%3D27504343%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1329469580 

似乎我对请求的签名无效。

我希望有人可以帮我找到这些请求的正确签名。

我知道有一个FlickNet库已经为大多数开发人员付出了艰苦的努力,但我认为让这个工作也很有用。 我查看了FlickrNet的源代码,但没有找到完成此代码的最终安静。

如果你能帮助我,请告诉我。 太棒了!

谢谢!

好的,我终于找到了答案。 在签署oauth请求时,您需要记住以下几点。

  1. 签名必须用HMAC-SHA1加密,使用basestring(参见nr.2)作为要加密的文本和clientsecret以及token_secret(如果有的话)(参见编号3)
  2. basestring = [HttpMethod]&[FlickrAPIEndpoint]&[Parameters]
  3. 请求密钥oauth_token = [ApiSecret]&(或key = [ApiSecret]&[Oauth_token_secret]请求access_token)

重要提示:FlickrAPIEndPoint和Parameters必须是UrlEncoded(分为两部分!)我使用了一个单独的类进行编码,因为HttpUtility.UrlEncode方法使用小写编码,而应该使用大写编码。

重要信息:参数必须按字母顺序排列!

以下是控制台应用程序的代码,该应用程序将为请求令牌和请求令牌机密创建签名请求。

 class Program { private static string Secret = "9dcc18a121e9a02e"; private static string ConsumerKey = "3aafc63ec6b05f3f9a9ff3a1c35ce541"; private static string request_token = ""; static void Main(string[] args) { string requestString = "http://www.flickr.com/services/oauth/request_token"; //generate a random nonce and a timestamp Random rand = new Random(); string nonce = rand.Next(999999).ToString(); string timestamp = GetTimestamp(); //create the parameter string in alphabetical order string parameters = "oauth_callback=" + UrlHelper.Encode("http://www.example.com"); parameters += "&oauth_consumer_key=" + ConsumerKey; parameters += "&oauth_nonce=" + nonce; parameters += "&oauth_signature_method=HMAC-SHA1"; parameters += "&oauth_timestamp=" + timestamp; parameters += "&oauth_version=1.0"; //generate a signature base on the current requeststring and parameters string signature = generateSignature("GET", requestString, parameters); //add the parameters and signature to the requeststring string url = requestString + "?" + parameters + "&oauth_signature=" + signature; //test the request WebClient web = new WebClient(); string result = web.DownloadString(url); Console.WriteLine("Flickr Response: "); Console.WriteLine(result); //contains the oauth_token and the oauth_token_secret Console.ReadKey(true); } private static string generateSignature(string httpMethod, string ApiEndpoint, string parameters) { //url encode the API endpoint and the parameters //IMPORTANT NOTE: //encoded text should contain uppercase characters: '=' => %3D !!! (not %3d ) //the HtmlUtility.UrlEncode creates lowercase encoded tags! //Here I use a urlencode class by Ian Hopkins string encodedUrl = UrlHelper.Encode(ApiEndpoint); string encodedParameters = UrlHelper.Encode(parameters); //generate the basestring string basestring = httpMethod + "&" + encodedUrl + "&"; parameters = UrlHelper.Encode(parameters); basestring = basestring + parameters; //hmac-sha1 encryption: System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); //create key (request_token can be an empty string) string key = Secret + "&" + request_token; byte[] keyByte = encoding.GetBytes(key); //create message to encrypt byte[] messageBytes = encoding.GetBytes(basestring); //encrypt message using hmac-sha1 with the provided key HMACSHA1 hmacsha1 = new HMACSHA1(keyByte); byte[] hashmessage = hmacsha1.ComputeHash(messageBytes); //signature is the base64 format for the genarated hmac-sha1 hash string signature = System.Convert.ToBase64String(hashmessage); //encode the signature to make it url safe and return the encoded url return UrlHelper.Encode(signature); } //generator of unix epoch time public static String GetTimestamp() { int epoch = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; return epoch.ToString(); } } 

Ian Hopkins的UrlHelper类用于url编码

 ///  /// URL encoding class. Note: use at your own risk. /// Written by: Ian Hopkins (http://www.lucidhelix.com) /// Date: 2008-Dec-23 /// (Ported to C# by t3rse (http://www.t3rse.com)) ///  public class UrlHelper { public static string Encode(string str) { var charClass = String.Format("0-9a-zA-Z{0}", Regex.Escape("-_.!~*'()")); return Regex.Replace(str, String.Format("[^{0}]", charClass), new MatchEvaluator(EncodeEvaluator)); } public static string EncodeEvaluator(Match match) { return (match.Value == " ") ? "+" : String.Format("%{0:X2}", Convert.ToInt32(match.Value[0])); } public static string DecodeEvaluator(Match match) { return Convert.ToChar(int.Parse(match.Value.Substring(1), System.Globalization.NumberStyles.HexNumber)).ToString(); } public static string Decode(string str) { return Regex.Replace(str.Replace('+', ' '), "%[0-9a-zA-Z][0-9a-zA-Z]", new MatchEvaluator(DecodeEvaluator)); } } 

你是从头开始写这个吗? 如果是这样,你不应该。 请改用http://flickrnet.codeplex.com/ 。 这个图书馆已经为你完成了繁重的工作。