HttpClient只有在运行Fiddler时才能正常工作

5
public async Task<LoginResult> Login(string username, string password)
    {
        cookies = new CookieContainer();
        handler = new HttpClientHandler()
        {
            CookieContainer = cookies,
            UseCookies = true,
            AllowAutoRedirect = true,
            UseProxy = true,
            Proxy = null
        };
        ThreadActivity.Account = username;
        ThreadActivity.Status = "Logging in...";
        LoginResult result = new LoginResult();
        try
        {
            cookies = new CookieContainer();
            client = new HttpClient(handler);
            client.DefaultRequestHeaders.Connection.Add("keep-alive");
            client.DefaultRequestHeaders.CacheControl = new CacheControlHeaderValue() { MaxAge = TimeSpan.Zero };
            client.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
            client.DefaultRequestHeaders.Add("Accept-Encoding", "gzip,deflate,sdch");
            client.DefaultRequestHeaders.Add("Accept-Language", "en-US,en;q=0.8");
            client.DefaultRequestHeaders.Add("Accept-Charset", "ISO-8859-1");
            client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36");

            HttpResponseMessage hr = await client.GetAsync("https://instagram.com/accounts/login/#");
            if (!hr.IsSuccessStatusCode)
                throw new Exception("Couldn't load instagram page; " + hr.ReasonPhrase);
            string source = await hr.Content.ReadAsStringAsync();
            //Get login token
            string token = ParseFormNameText(source, "csrfmiddlewaretoken");
            //Login
            HttpContent content = new FormUrlEncodedContent(new[]
            {
                    new KeyValuePair<string,string>("csrfmiddlewaretoken", token),
                    new KeyValuePair<string, string>("username", username),
                    new KeyValuePair<string, string>("password", password)
            });
            client.DefaultRequestHeaders.Referrer = new Uri("https://instagram.com/accounts/login/");
            hr = await client.PostAsync("https://instagram.com/accounts/login/", content);
            if (!hr.IsSuccessStatusCode)
                throw new Exception("Couldn't submit login; " + hr.ReasonPhrase);
            source = await hr.Content.ReadAsStringAsync();
            if (source.Contains("Please enter a correct username and password"))
                throw new Exception("Couldn't login; invalid username/password.");
            //Logged in, login to webstagram now
            hr = await client.GetAsync("https://instagram.com/oauth/authorize/?client_id=9d836570317f4c18bca0db6d2ac38e29&redirect_uri=http://web.stagram.com/&response_type=code&scope=likes+comments+relationships");
            if (!hr.IsSuccessStatusCode)
                throw new Exception("Couldn't load webstagram login; " + hr.ReasonPhrase);
            source = await hr.Content.ReadAsStringAsync();
            if (!source.Contains(">LOG OUT</a>"))
                throw new Exception("Couldn't load webstagram; failed to login.");
            RaiseEvent("Logged in!", this);
        }
        catch (Exception ex)
        {
            RaiseEvent(ex.Message, this);
            result.ErrorMessage = ex.Message;
        }
        finally
        {
            result.Success = string.IsNullOrEmpty(result.ErrorMessage);
        }
        return result;
    }

这是我的登录方法,但实际尝试提交登录时,我遇到了403禁止错误。但是当我使用Fiddler运行时,它可以正常工作。不太清楚原因,希望有人可以帮忙解决。

你的HTTP/403响应体中包含什么? - EricLaw
此外,您不应该像这样自行设置“Accept-Encoding”标头,因为如果服务器使用您声称接受的编码之一,您的代码将失败。 - EricLaw
1个回答

2

我曾经遇到过类似的问题。问题在于Fiddler在拦截流量时改变了请求。我们的情况下代理服务器被配置为阻止此类请求(ASP.net请求失败)"CONNECT www.20min.ch",而Fiddler将请求更改为"CONNECT http://www.20min.ch",这是允许通过代理的(成功了)。也许你需要使用Wireshark比较Fiddler和ASP.net的请求,并查找它们之间的差异。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接