【问题标题】:Twitter home_timeline Windows 8 C# call returns Could not authenticate youTwitter home_timeline Windows 8 C# 调用返回 无法对您进行身份验证
【发布时间】:2014-06-17 23:06:51
【问题描述】:

我正在尝试在 Windows 8.1/Windows Phone 8.1 通用应用中提取经过身份验证的用户的时间线。我相信我已经正确设置了所有内容,但我在 Fiddler 中不断收到“code=32, message=Could not authenticate you”的响应。

我认为我只是在 TwitterGetRequest 函数中使用了错误的标头,但我无法弄清楚确切的问题。

这一切都基于来自 MSDN 的 WebAuthentication 示例代码。

这里是主要功能

private async Task GetTwitterUserNameAsync(string webAuthResultResponseData)
    {
        //
        // Acquiring a access_token first
        //

        string responseData = webAuthResultResponseData.Substring(webAuthResultResponseData.IndexOf("oauth_token"));
        string request_token = null;
        string oauth_verifier = null;
        String[] keyValPairs = responseData.Split('&');

        for (int i = 0; i < keyValPairs.Length; i++)
        {
            String[] splits = keyValPairs[i].Split('=');
            switch (splits[0])
            {
                case "oauth_token":
                    request_token = splits[1];
                    break;
                case "oauth_verifier":
                    oauth_verifier = splits[1];
                    break;
            }
        }

        String TwitterUrl = "https://api.twitter.com/oauth/access_token";

        string response = await TwitterPostRequest(request_token, oauth_verifier, TwitterUrl);

        String[] Tokens = response.Split('&');
        string oauth_token_secret = null;
        string access_token = null;
        string screen_name = null;

        for (int i = 0; i < Tokens.Length; i++)
        {
            String[] splits = Tokens[i].Split('=');
            switch (splits[0])
            {
                case "screen_name":
                    screen_name = splits[1];
                    break;
                case "oauth_token":
                    access_token = splits[1];
                    break;
                case "oauth_token_secret":
                    oauth_token_secret = splits[1];
                    break;
            }
        }

        //you can store access_token and oauth_token_secret for further use. See Scenario5(Account Management).
        if (access_token != null)
        {
            DebugPrint("access_token = " + access_token);
        }

        if (oauth_token_secret != null)
        {
            DebugPrint("oauth_token_secret = " + oauth_token_secret);
        }
        if (screen_name != null)
        {
            //rootPage.NotifyUser(screen_name + " is connected!!", NotifyType.StatusMessage);
        }

        string timeline = await TwitterGetRequest(access_token, oauth_token_secret, oauth_verifier, "https://api.twitter.com/1.1/statuses/home_timeline.json");

        List<SocialItem> tweets = new List<SocialItem>();

        if (timeline.Length > 0)
        {
            JArray tweetArray = JArray.Parse(timeline);
            for(int i=0;i<tweetArray.Count();i++)
            {
                JObject tweet = JObject.Parse(tweetArray[i].ToString());
                JObject tweetAuthor = JObject.Parse(tweet["user"].ToString());
                string imgUrl = tweetAuthor["profile_image_url"].ToString();
                string message = tweet["text"].ToString();
                string userName = tweetAuthor["screen_name"].ToString();
                string displayName = tweetAuthor["name"].ToString();
                string createdAtString = tweet["created_at"].ToString();
                DateTime created;
                if(!DateTime.TryParse(createdAtString, out created))
                {
                    created = DateTime.MinValue;
                }

                tweets.Add(new SocialItem
                {
                    ImageUrl = imgUrl,
                    MessageBody = message,
                    UserName = userName,
                    DisplayName = displayName,
                    MessageDate = created,
                    ProfileUrl = ("http://twitter.com/" + userName)
                });
            }

            this.DataContext = tweets;
        }
    }

以下是支持功能:

private async Task<string> TwitterPostRequest(string request_token, string oauth_verifier, String TwitterUrl)
    {
        string timeStamp = GetTimeStamp();
        string nonce = GetNonce();

        String SigBaseStringParams = "oauth_consumer_key=" + Twitter.CLIENT_ID;
        SigBaseStringParams += "&" + "oauth_nonce=" + nonce;
        SigBaseStringParams += "&" + "oauth_signature_method=HMAC-SHA1";
        SigBaseStringParams += "&" + "oauth_timestamp=" + timeStamp;
        SigBaseStringParams += "&" + "oauth_token=" + request_token;
        SigBaseStringParams += "&" + "oauth_version=1.0";
        String SigBaseString = "POST&";
        SigBaseString += Uri.EscapeDataString(TwitterUrl) + "&" + Uri.EscapeDataString(SigBaseStringParams);

        String Signature = GetSignature(SigBaseString, Twitter.CLIENT_SECRET);

        HttpStringContent httpContent = new HttpStringContent("oauth_verifier=" + oauth_verifier, Windows.Storage.Streams.UnicodeEncoding.Utf8);
        httpContent.Headers.ContentType = HttpMediaTypeHeaderValue.Parse("application/x-www-form-urlencoded");
        string authorizationHeaderParams = "oauth_consumer_key=\"" + Twitter.CLIENT_ID + "\", oauth_nonce=\"" + nonce + "\", oauth_signature_method=\"HMAC-SHA1\", oauth_signature=\"" + Uri.EscapeDataString(Signature) + "\", oauth_timestamp=\"" + timeStamp + "\", oauth_token=\"" + Uri.EscapeDataString(request_token) + "\", oauth_version=\"1.0\"";

        HttpClient httpClient = new HttpClient();

        httpClient.DefaultRequestHeaders.Authorization = new HttpCredentialsHeaderValue("OAuth", authorizationHeaderParams);
        var httpResponseMessage = await httpClient.PostAsync(new Uri(TwitterUrl), httpContent);
        string response = await httpResponseMessage.Content.ReadAsStringAsync();
        return response;
    }

    private async Task<string> TwitterGetRequest(string request_token, string oauth_token_secret, string oauth_verifier, String TwitterUrl)
    {
        string timeStamp = GetTimeStamp();
        string nonce = GetNonce();

        String SigBaseStringParams = "oauth_consumer_key=" + Twitter.CLIENT_ID;
        SigBaseStringParams += "&" + "oauth_nonce=" + nonce;
        SigBaseStringParams += "&" + "oauth_signature_method=HMAC-SHA1";
        SigBaseStringParams += "&" + "oauth_timestamp=" + timeStamp;
        SigBaseStringParams += "&" + "oauth_token=" + request_token;
        SigBaseStringParams += "&" + "oauth_version=1.0";
        String SigBaseString = "GET&";
        SigBaseString += Uri.EscapeDataString(TwitterUrl) + "&" + Uri.EscapeDataString(SigBaseStringParams);

        String Signature = GetSignature(SigBaseString, oauth_token_secret);

        //HttpStringContent httpContent = new HttpStringContent("oauth_verifier=" + oauth_verifier, Windows.Storage.Streams.UnicodeEncoding.Utf8);
        //httpContent.Headers.ContentType = HttpMediaTypeHeaderValue.Parse("application/x-www-form-urlencoded");
        string authorizationHeaderParams = "oauth_consumer_key=\"" + Twitter.CLIENT_ID + 
                                           "\", oauth_nonce=\"" + nonce + 
                                           "\", oauth_signature_method=\"HMAC-SHA1\", oauth_signature=\"" + Uri.EscapeDataString(Signature) + 
                                           "\", oauth_timestamp=\"" + timeStamp + 
                                           "\", oauth_token=\"" + Uri.EscapeDataString(request_token) + 
                                           "\", oauth_version=\"1.0\"";

        HttpClient httpClient = new HttpClient();

        httpClient.DefaultRequestHeaders.Authorization = new HttpCredentialsHeaderValue("OAuth", authorizationHeaderParams);

        string response="";

        try
        {
            response = await httpClient.GetStringAsync(new Uri(TwitterUrl));//httpClient.PostAsync(new Uri(TwitterUrl), httpContent);
        }
        catch (Exception ex)
        {
            DebugPrint(ex.Message);
        }

        //string response = await httpResponseMessage.Content.ReadAsStringAsync();
        return response;
    }


    string GetNonce()
    {
        Random rand = new Random();
        int nonce = rand.Next(1000000000);
        return nonce.ToString();
    }

    string GetTimeStamp()
    {
        TimeSpan SinceEpoch = DateTime.UtcNow - new DateTime(1970, 1, 1);
        return Math.Round(SinceEpoch.TotalSeconds).ToString();
    }

    string GetSignature(string sigBaseString, string consumerSecretKey)
    {
        IBuffer KeyMaterial = CryptographicBuffer.ConvertStringToBinary(consumerSecretKey + "&", BinaryStringEncoding.Utf8);
        MacAlgorithmProvider HmacSha1Provider = MacAlgorithmProvider.OpenAlgorithm("HMAC_SHA1");
        CryptographicKey MacKey = HmacSha1Provider.CreateKey(KeyMaterial);
        IBuffer DataToBeSigned = CryptographicBuffer.ConvertStringToBinary(sigBaseString, BinaryStringEncoding.Utf8);
        IBuffer SignatureBuffer = CryptographicEngine.Sign(MacKey, DataToBeSigned);
        string Signature = CryptographicBuffer.EncodeToBase64String(SignatureBuffer);

        return Signature;
    }

【问题讨论】:

  • 我也有类似的问题,你解决了吗?
  • 不。仍然没有解决方案。

标签: c# rest twitter windows-8.1 dotnet-httpclient


【解决方案1】:

我从来没有收到过这种错误,但是我一直在使用Tweetinvi进行开发,并且很容易检索到经过身份验证的用户的时间线。

只需执行以下操作:

TwitterCredentials.SetCredentials("ACCESS_TOKEN", "ACCESS_TOKEN_SECRET", "CONSUMER_KEY", "CONSUMER_SECRET");
var tweets = Timeline.GetHomeTimeline();

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2022-01-01
    • 2011-08-04
    • 2013-02-15
    • 2021-04-14
    • 2023-03-15
    • 2017-07-11
    • 1970-01-01
    • 2015-04-01
    • 1970-01-01
    相关资源
    最近更新 更多