对Flickr API请求进行签名的签名无效(控制台中的模拟)

本文关键字:控制台 模拟 无效 Flickr API 请求 | 更新日期: 2023-09-27 18:24:54

我正在尝试向Flickr API验证我想要为自己制作的演示应用程序。然后,我将用Flick API的新功能来扩展这个应用程序。

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

我在这里关注Flickr身份验证文档:Flickr身份验证
我还发现了这个Mathlabscript:Flickr API,带有基于OAuth的用户身份验证

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

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的源代码,但没有找到完成这段代码的最终方法。

如果你能帮我的话,请告诉我。那太好了!

谢谢!

对Flickr API请求进行签名的签名无效(控制台中的模拟)

好吧,我终于自己找到了答案。在签署oauth请求时,您必须记住以下几点。

  1. 签名必须使用HMAC-SHA1加密,使用作为要加密的文本的基字符串(请参见第2条)以及clientsecret和token_secret(如果您有)(请参阅第3条)
  2. basestring=[HttpMethod]&[FickrAPIendpoint]&[参数]
  3. 请求的密钥oauth_token=[ApiSecret]&(对于请求access_token,密钥=[ApiSecret]&[Oauth_token_secret])

重要事项: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编码

/// <summary> 
    /// 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)) 
    /// </summary> 
    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/相反这个图书馆已经为你完成了繁重的工作。