C#Web客户端登录到accounts.google.com [英] C# WebClient login to accounts.google.com

查看:214
本文介绍了C#Web客户端登录到accounts.google.com的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经很困难的时候试图用accounts.google.com时验证Web客户端

I have very difficult time trying to authenticate to accounts.google.com using webclient

我使用C#WebClient的对象来实现以下。

I'm using C# WebClient object to achieve following.

我提交表单字段 https://accounts.google.com/ServiceLoginAuth ?服务=盎司

下面是POST领域:

service=oz
dsh=-8355435623354577691
GALX=33xq1Ma_CKI
timeStmp=
secTok=
Email=test@test.xom
Passwd=password
signIn=Sign in
PersistentCookie=yes
rmShown=1

现在,当登录页面加载我提交数据之前,它具有以下标题:

Now when login page loads before I submit data it has following headers:

Content-Type                text/html; charset=UTF-8
Strict-Transport-Security   max-age=2592000; includeSubDomains
Set-Cookie                  GAPS=1:QClFh_dKle5DhcdGwmU3m6FiPqPoqw:SqdLB2u4P2oGjt_x;Path=/;Expires=Sat, 21-Dec-2013 07:31:40 GMT;Secure;HttpOnly
Cache-Control               no-cache, no-store
Pragma                      no-cache
Expires                     Mon, 01-Jan-1990 00:00:00 GMT
X-Frame-Options             Deny
X-Auto-Login                realm=com.google&args=service%3Doz%26continue%3Dhttps%253A%252F%252Faccounts.google.com%252FManageAccount
Content-Encoding            gzip
Transfer-Encoding           chunked
Date                        Thu, 22 Dec 2011 07:31:40 GMT
X-Content-Type-Options      nosniff
X-XSS-Protection            1; mode=block
Server                      GSE



OK,现在我怎么使用WebClient类包括那些头?

OK now how do I use WebClient Class to include those headers?

我曾尝试 webClient_.Headers.Add(); 但它具有有限的影响,始终返回登录页面

I have tried webClient_.Headers.Add(); but it has limited effect and always returns login page.

下面是我使用的类。希望得到任何帮助。

Below is a class that I use. Would appreciate any help.

获取登录页

    public void LoginPageRequest(Account acc)
    {

        var rparams = new RequestParams();
        rparams.URL = @"https://accounts.google.com/ServiceLoginAuth?service=oz";
        rparams.RequestName = "LoginPage";
        rparams.Account = acc;

        webClient_.DownloadDataAsync(new Uri(rparams.URL), rparams);
    }

    void webClient__DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
    {
        RequestParams rparams = (RequestParams)e.UserState;

        if (rparams.RequestName == "LoginPage")
        {
            ParseLoginRequest(e.Result, e.UserState);
        }
    }

现在让使用HtmlAgilityPack表单域和将它们添加到参数集合

Now getting form fields using HtmlAgilityPack and adding them into Parameters collection

    public void ParseLoginRequest(byte[] data, object UserState)
    {
        RequestParams rparams = (RequestParams)UserState;

        rparams.ClearParams();

        ASCIIEncoding encoder = new ASCIIEncoding();

        string html = encoder.GetString(data);

        HtmlNode.ElementsFlags.Remove("form");

        HtmlDocument doc = new HtmlDocument();
        doc.LoadHtml(html);

        HtmlNode form = doc.GetElementbyId("gaia_loginform");

        rparams.URL = form.GetAttributeValue("action", string.Empty);
        rparams.RequestName = "LoginPost";

        var inputs = form.Descendants("input");
        foreach (var element in inputs)
        {
            string name = element.GetAttributeValue("name", "undefined");
            string value = element.GetAttributeValue("value", "");
            if (!name.Equals("undefined")) {

                if (name.ToLower().Equals("email"))
                {
                    value = rparams.Account.Email;
                }
                else if (name.ToLower().Equals("passwd"))
                {
                    value = rparams.Account.Password;
                }

                rparams.AddParam(name,value);
                Console.WriteLine(name + "-" + value);
            }
        }

        webClient_.UploadValuesAsync(new Uri(rparams.URL),"POST", rparams.GetParams,rparams);



我发布数据后,我得到的登录页面,而不是重定向或成功的消息。

After I post the data I get login page rather than redirect or success message.

我在做什么错了?

推荐答案

一些摆弄周围后,它看起来像WebClient类是不是这个特殊问题的最佳途径。

After some fiddling around, it looks like the WebClient class is not the best approach to this particular problem.

要实现以下目标,我有以下跳到一个等级至WebRequest的。

To achieve following goal I had to jump one level below to WebRequest.

当制作的WebRequest(HttpWebRequest的),并使用HttpWebResponse能够设定的CookieContainer

When making WebRequest (HttpWebRequest) and using HttpWebResponse it is possible to set CookieContainer

        webRequest_ = (HttpWebRequest)HttpWebRequest.Create(rparams.URL);

        webRequest_.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
        CookieContainer cookieJar = new CookieContainer();
        webRequest_.CookieContainer = cookieJar;

        string html = string.Empty;

        try
        {
            using (WebResponse response = webRequest_.GetResponse())
            {
                using (var streamReader = new StreamReader(response.GetResponseStream()))
                {
                    html = streamReader.ReadToEnd();
                    ParseLoginRequest(html, response,cookieJar);
                }
            }
        }
        catch (WebException e)
        {
            using (WebResponse response = e.Response)
            {
                HttpWebResponse httpResponse = (HttpWebResponse)response;
                Console.WriteLine("Error code: {0}", httpResponse.StatusCode);
                using (var streamReader = new StreamReader(response.GetResponseStream()))
                    Console.WriteLine(html = streamReader.ReadToEnd());
            }
        }



然后做后期使用相同的cookie容器中时,下面的方式

and then when making post use the same Cookie Container in following manner

        webRequest_ = (HttpWebRequest)HttpWebRequest.Create(rparams.URL);

        webRequest_.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
        webRequest_.Method = "POST";
        webRequest_.ContentType = "application/x-www-form-urlencoded";
        webRequest_.CookieContainer = cookieJar;

        var parameters = new StringBuilder();

        foreach (var key in rparams.Params)
        {
            parameters.AppendFormat("{0}={1}&",HttpUtility.UrlEncode(key.ToString()),
                HttpUtility.UrlEncode(rparams.Params[key.ToString()]));
        }

        parameters.Length -= 1;

        using (var writer = new StreamWriter(webRequest_.GetRequestStream()))
        {
            writer.Write(parameters.ToString());
        }

        string html = string.Empty;

        using (response = webRequest_.GetResponse())
        {
            using (var streamReader = new StreamReader(response.GetResponseStream()))
            {
                html = streamReader.ReadToEnd();

            }
        }



所以这个作品,这个代码是不为生产使用,并且可以/应当被优化。
对待它只是作为一个例子。

So this works, this code is not for production use and can be/should be optimized. Treat it just as an example.

这篇关于C#Web客户端登录到accounts.google.com的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆