2011-12-22 91 views
7

Tôi có thời gian rất khó khăn để cố gắng xác thực với accounts.google.com bằng cách sử dụng webclientC# WebClient đăng nhập vào accounts.google.com

Tôi đang sử dụng đối tượng C# WebClient để đạt được sau đây.

Tôi nộp trường biểu mẫu để https://accounts.google.com/ServiceLoginAuth?service=oz

Đây là POST Fields:

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

Bây giờ khi trang đăng nhập tải trọng trước khi tôi gửi dữ liệu nó có tiêu đề sau:

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 bây giờ làm cách nào để sử dụng Lớp WebClient để bao gồm các tiêu đề đó?

Tôi đã thử webClient_.Headers.Add(); nhưng nó có tác dụng hạn chế và luôn trả về trang đăng nhập.

Dưới đây là lớp tôi sử dụng. Sẽ đánh giá cao sự giúp đỡ nào.


Bắt trang đăng nhập

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

Bây giờ nhận được các lĩnh vực hình thức sử dụng HtmlAgilityPack và thêm chúng vào bộ sưu tập thông số

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

Sau khi tôi gửi dữ liệu tôi có được trang đăng nhập chứ không phải chuyển hướng hoặc thành công thông điệp.

Tôi đang làm gì sai?

Trả lời

4

Sau khi một số không quan sát xung quanh, có vẻ như lớp WebClient không phải là cách tiếp cận tốt nhất cho vấn đề cụ thể này.

Để đạt được mục tiêu sau, tôi phải nhảy một cấp dưới đây để WebRequest.

Khi thực hiện WebRequest (HttpWebRequest) và sử dụng HttpWebResponse nó có thể thiết lập 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()); 
      } 
     } 

và sau đó khi làm bài sử dụng cùng một Cookie container ở sau cách

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

      } 
     } 

Vì vậy, công trình này, mã này không dành cho việc sử dụng sản xuất và có thể/nên được tối ưu hóa. Hãy coi nó như một ví dụ.

+0

tôi có thể làm việc này, bạn có thể đăng dự án mẫu không? – Smith

3

Đây là ví dụ nhanh được viết trong ngăn câu trả lời và chưa được kiểm tra. Bạn có thể sẽ cần phải phân tích một số giá trị trong một yêu cầu ban đầu cho một số giá trị biểu mẫu để đi vào formData. Rất nhiều mã của tôi dựa trên loại quy trình này trừ khi chúng ta cần phải loại bỏ các trang web loại facebook spokeo trong trường hợp ajax làm cho chúng ta sử dụng một cách tiếp cận khác.

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

Có vẻ như bạn Rob tham gia vào cùng một ngành như tôi, sẽ rất muốn liên lạc với bạn để thảo luận về một số AJAX aproaches mà bạn đã đề cập trong bài đăng này – Tim

+0

Đã gửi cho bạn lời mời FB –

Các vấn đề liên quan