401尝试获取请求令牌时出错

时间:2011-08-12 13:55:16

标签: c# twitter oauth twitter-oauth

resp =(HttpWebResponse)request.GetResponse();对,我知道这可能是一些愚蠢的错误,或者只是我不熟悉Oauth的东西,但我已经停止了,不知道从哪里开始经过多次搜索和尝试后,我谦卑地寻求帮助。

我正在尝试从Twitter获取请求令牌以尝试获取用户的Twitter订阅源,我出于其他商业原因无法使用库...

以下是目前的代码:

     Dictionary<string, string> parameters = new Dictionary<string, string>();
        parameters.Add("oauth_callback", "www.url.com/redirect.aspx");
        parameters.Add("oauth_consumer_key", <Consumer_KEY>);
        parameters.Add("oauth_nonce", generateNonce());
        parameters.Add("oauth_signature_method", "HMAC-SHA1");
        parameters.Add("oauth_timestamp", CurrentUNIXTimestamp.Get());
        parameters.Add("oauth_version", "1.0");

        parameters = parameters.OrderBy(x => x.Key).ToDictionary(v => v.Key, v => v.Value);
        string concat = "";
        string OAuthHeader = "OAuth ";
        foreach (string k in parameters.Keys)
        {
            if (k == "oauth_callback")
            {
                concat += k + "%3D" + EncodeToUpper(parameters[k]) + "%26";
                OAuthHeader += k + "=" + "\"" + EncodeToUpper(parameters[k]) + "\", ";
            }
            else
            {
                concat += k + "%3D" + parameters[k] + "%26";
                OAuthHeader += k + "=" + "\"" + parameters[k] + "\", ";
            }

        }

        concat = concat.Remove(concat.Length - 3, 3);

        concat = "POST&" + EncodeToUpper("https://api.twitter.com/oauth/request_token" ) + "&" + concat;

        //byte[] content = Encoding.UTF8.GetBytes(concat);

        HMACSHA1 hmacsha1 = new HMACSHA1();
        hmacsha1.Key = Encoding.ASCII.GetBytes(string.Format("{0}&{1}", EncodeToUpper(<CONSUMER SECRET>, ""));

        byte[] dataBuffer = System.Text.Encoding.ASCII.GetBytes(concat);
        byte[] hashBytes = hmacsha1.ComputeHash(dataBuffer);

        string hash =  Convert.ToBase64String(hashBytes);
        OAuthHeader += "oauth_signature=\"" + EncodeToUpper(hash) + "\"";

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://api.twitter.com/oauth/request_token");
        request.Method = "POST";
        request.Headers["Authorization"] = OAuthHeader;

        StringBuilder responding = new StringBuilder();
        HttpWebResponse resp = null;
        try
        {
            resp = (HttpWebResponse)request.GetResponse();
        }
        catch (WebException exc)
        {
            lblError.Text = "Error Connecting to Social Network " + exc.Message;
        }
        if (resp != null)
        {
            using (StreamReader reader = new StreamReader(resp.GetResponseStream()))
            {
                responding.Append(reader.ReadToEnd());
            }
        }

Nonce的示例是“ne8ehvVr0pW2EUxNHdxdyqbi8Fwphatt3SW1yerTyXH”,并且CurrentUNIXTimestamp由

生成
         public static class CurrentUNIXTimestamp
         {
              public static string Get()
              {
                    return Convert.ToString((int)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds);
               }
         }

我尝试了很多我能想到的东西,不再有客户端/浏览器问题(这是许多其他答案),服务器时间对英国夏令时是正确的(我不知道是否会是一个问题,但我尝试添加一个小时到unix时间戳仍然是401.),我已经在Twitter应用页面上定义了回调网址

我有相同的应用程序与Facebook合作(我知道它的不同oauth但可能有帮助)

实际错误来自resp =(HttpWebResponse)request.GetResponse();,它出现了401错误。我无法从exc.response对象中获得任何进一步的细节,有人可以说如何从VS2008中的错误中获得有用的东西吗?

感谢您的回答

1 个答案:

答案 0 :(得分:0)

我实施OAuth的最难的问题是处理字符编码。这非常特别。

以下是我为此编写的代码。

private static string UrlEncode(IEnumerable<KeyValuePair<string, object>> parameters)
{
    StringBuilder parameterString = new StringBuilder();

    var paramsSorted = from p in parameters
                       orderby p.Key, p.Value
                       select p;

    foreach (var item in paramsSorted)
    {
        if (parameterString.Length > 0)
        {
            parameterString.Append("&");
        }

        if(item.Value.GetType() == typeof(string) )
                parameterString.Append(
                        string.Format(
                                CultureInfo.InvariantCulture,
                                "{0}={1}",
                                UrlEncode(item.Key),
                                UrlEncode(item.Value as string)));
    }

    return UrlEncode(parameterString.ToString());
}

public static string UrlEncode(string value)
{
    if (string.IsNullOrEmpty(value))
    {
        return string.Empty;
    }

    value = Uri.EscapeDataString(value);

    // UrlEncode escapes with lowercase characters (e.g. %2f) but oAuth needs %2F
    value = Regex.Replace(value, "(%[0-9a-f][0-9a-f])", c => c.Value.ToUpper());

    // these characters are not escaped by UrlEncode() but needed to be escaped
    value = value
        .Replace("(", "%28")
        .Replace(")", "%29")
        .Replace("$", "%24")
        .Replace("!", "%21")
        .Replace("*", "%2A")
        .Replace("'", "%27");

    // these characters are escaped by UrlEncode() but will fail if unescaped!
    value = value.Replace("%7E", "~");

    return value;
}

如果你真的厌倦了,你可以使用我库中的WebRequestBuilder类来为你做所有的OAuth:http://www.twitterizer.net/