HttpWebResponseのCookieを再利用して、Webページにログインしたままにする方法はありますか?

c# cookies html-agility-pack httpwebrequest wpf

質問

私は、XenForoフォーラムサイトを閲覧し、クッキーを取り出し、さらにポストデータをログインに送信し、ログインしたユーザーのみが利用可能な情報を取得する単純なアプリケーションを使用した場合があります。

私は正常にクッキーを取得し、私が正常に初めてログインしたことを確認することができますが、私は同じクッキーを再利用しようとするときに私が "ブラウズ"しようとするとログインしているようだ。

ここまで私はこれまで何を得ているのですか?

public MainWindow()
{
    InitializeComponent();
    if (IsLoggedIn())
    {
        GetPage("http://thesiteiloginto.org/someotherpage");
    }
}

// Store Cookies
CookieCollection Cookies;

void GetCookies(string cookieUrl)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(cookieUrl);
    request.CookieContainer = new CookieContainer();
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    using (Stream responseStream = response.GetResponseStream())
    {
        // Store Cookies
        Cookies = response.Cookies;
    }
}

bool IsLoggedIn()
{
    GetCookies(_cookieUrl);
    CookieCollection cookies = Cookies;
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(loginUrl);
    request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)";
    request.CookieContainer = new CookieContainer();
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";
    string postData = "login=" + username +
                        "&password=" + password +
                        "&_xfToken=" + xfToken +
                        "&cookie_check=" + cookie_check +
                        "&redirect=" + redirect;
    byte[] bytes = Encoding.UTF8.GetBytes(postData);
    request.ContentLength = bytes.Length;
    if (cookies != null)
    {
        Console.WriteLine("Cookies are present");
        Console.WriteLine(Cookies.Count);
        Console.WriteLine(Cookies[0].Value);
        request.CookieContainer.Add(cookies);
    }
    using (Stream requestStream = request.GetRequestStream())
    {
        requestStream.Write(bytes, 0, bytes.Length);
        WebResponse response = request.GetResponse();
        using (Stream stream = response.GetResponseStream())
        {
            using (StreamReader reader = new StreamReader(stream))
            {
                HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
                doc.LoadHtml(reader.ReadToEnd());
                bool _loggedIn = false;
                try
                {
                    var uniqueNodeTest = doc.DocumentNode.SelectSingleNode("//*[@id=\"navigation\"]/div/nav/div/ul[2]/li[1]/a/strong[1]");
                    if (uniqueNodeTest.InnerText.Trim().ToLower() == uniqueNodeName)
                    {
                        Console.WriteLine("Logged in");
                        _loggedIn = true;
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Ops! [Login] @ SelectSingleNode\n" + ex.Message);
                    _loggedIn = false;
                }
                return _loggedIn;
            }
        }
    }
}

void GetPage(string url)
{
    if (Cookies != null)
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        request.PreAuthenticate = true;
        request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)";
        request.CookieContainer = new CookieContainer();
        request.CookieContainer.Add(Cookies);
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        using (Stream responseStream = response.GetResponseStream())
        {
            using (StreamReader reader = new StreamReader(responseStream))
            {
                var pageSource = reader.ReadToEnd();

                // Retuns false, meaning i am not logged in
                //Where do i go from here?
                Console.WriteLine(pageSource.Contains("Log Out"));
            }
        }
    }
}

コンソール:

Cookies are present 1 22a6c5a4c5557a7f7db36f50a1d746f1 Logged in False

あなたが見ることができるように、私は最初のテストの後にログインしていますが、クッキーの再利用をブラウズしようとするとログインできないようです。

私は何を考慮していないのですか?どうすればサイトにログインできますか?

受け入れられた回答

それらをローカルに格納するクラスとしてCookieContainerを使用します。

レスポンスを取得するときは、すべてのCookieをCookieContainerに入れます。要求を準備するときは、新しい呼び出しでrequest.CookieContainerを独自のオブジェクトに設定するだけです。

これは、私のプロジェクトにクッキーを保存するために使用したコードです。それはあなたがやっているリクエストの種類を具体的に意味するHttpSessionクラスの一部ですので、レスポンスとクッキーコンテナの両方がクラス変数であることに気付くでしょう。

/// <summary>
///     Fetches the new cookies and saves them in the cookie jar.
/// </summary>
private void SaveNewCookies()
{
    try
    {
        foreach (Cookie c in this.m_HttpWebResponse.Cookies)
        {
            if (c.Domain.Length > 0 && c.Domain[0] == '.')
                c.Domain = c.Domain.Remove(0, 1);
            this.m_CookieJar.Add(new Uri(this.m_HttpWebResponse.ResponseUri.Scheme + "://" + c.Domain), c);
        }
        if (this.m_HttpWebResponse.Cookies.Count > 0)
            this.BugFixCookieDomain(this.m_CookieJar);
    }
    catch
    {
        // no new cookies
    }
}

ご覧のとおり、これにはいくつかの小さなバグ修正も含まれています。上記のBugFixCookieDomain関数は、特にここで見つけることができる3.5フレームワーク用の修正ですが、それを4.0以上に移動してもそれは特に役に立ちません。




ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ