2011-12-22 3 views
7

У меня очень трудное время пытается аутентифицировать в accounts.google.com с помощью WebClientC# WebClient Войти в accounts.google.com

Я использую C# WebClient объект для достижения следующих.

Я представление полой формы https://accounts.google.com/ServiceLoginAuth?service=oz

Вот POST Поле:

service=oz 
dsh=-8355435623354577691 
GALX=33xq1Ma_CKI 
timeStmp= 
secTok= 
[email protected] 
Passwd=password 
signIn=Sign in 
PersistentCookie=yes 
rmShown=1 

Теперь, когда страница загружается Войти, прежде чем я представить данные, которые он имеет следующие заголовки:

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 для включения этих заголовков?

Я пробовал webClient_.Headers.Add();, но он имеет ограниченный эффект и всегда возвращает страницу входа.

Ниже приведен класс, который я использую. Поблагодарили бы за любую помощь.


Попадая Войти страницу

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 и добавление их в коллекцию Parameters

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); 

После того как я выкладываю данные я получаю страницу входа, а не перенаправлять или успех сообщение.

Что я делаю неправильно?

ответ

4

После некоторого возиться, похоже, что класс WebClient не лучший подход к этой конкретной проблеме.

Для достижения следующей цели я должен был перейти на один уровень ниже к WebRequest.

При создании WebRequest (HttpWebRequest) и с помощью HttpWebResponse можно установить 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 контейнер в следующем порядке

 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(); 

      } 
     } 

Так что это работает, этот код не предназначен для использования в производстве и может быть/должен быть оптимизирован. Рассматривайте это как пример.

+0

Я могу заставить это работать, можете ли вы опубликовать образец проекта? – Smith

3

Это быстрый пример, написанный на панели ответов и непроверенный. Вероятно, вам нужно будет проанализировать некоторые значения из первоначального запроса для некоторых значений формы, которые входят в formData. Многие из моих кодов основаны на этом типе процесса, если нам не нужно очищать сайты на языке говорящего типа facebook, и в этом случае ajax заставляет нас использовать другой подход.

using System; 
using System.Collections.Generic; 
using System.Collections.Specialized; 
using System.Linq; 
using System.Text; 

namespace GMailTest 
{ 
    class Program 
    { 
     private static NameValueCollection formData = new NameValueCollection(); 
     private static CookieAwareWebClient webClient = new CookieAwareWebClient(); 

     static void Main(string[] args) 
     { 
      formData.Clear(); 
      formData["service"] = "oz"; 
      formData["dsh"] = "-8355435623354577691"; 
      formData["GALX"] = "33xq1Ma_CKI"; 
      formData["timeStmp"] = ""; 
      formData["secTok"] = ""; 
      formData["Email"] = "[email protected]"; 
      formData["Passwd"] = "password"; 
      formData["signIn"] = "Sign in"; 
      formData["PersistentCookie"] = "yes"; 
      formData["rmShown"] = "1"; 

      byte[] responseBytes = webClient.UploadValues("https://accounts.google.com/ServiceLoginAuth?service=oz", "POST", formData); 
      string responseHTML = Encoding.UTF8.GetString(responseBytes); 
     } 
    } 

    public class CookieAwareWebClient : WebClient 
    { 
     public CookieAwareWebClient() : this(new CookieContainer()) 
     { } 

     public CookieAwareWebClient(CookieContainer c) 
     { 
      this.CookieContainer = c; 
      this.Headers.Add("User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.52 Safari/536.5"); 
     } 

     public CookieContainer CookieContainer { get; set; } 

     protected override WebRequest GetWebRequest(Uri address) 
     { 
      WebRequest request = base.GetWebRequest(address); 
      if (request is HttpWebRequest) 
      { 
       (request as HttpWebRequest).CookieContainer = this.CookieContainer; 
      } 
      return request; 
     } 
    } 
} 
+1

Похоже, вы, Роб, вовлечены в ту же отрасль, что и я, были бы рады связаться с вами, чтобы обсудить некоторые аплоады AJAX, которые вы упомянули в этом сообщении. – Tim

+0

Прислал вам приглашение FB –