2012-03-06 9 views
5

से वेबसाइट पर प्रमाणीकरण में समस्याएं मैं कोड लिखने की कोशिश कर रहा हूं जो वेबसाइट wallbase.cc को प्रमाणित करेगा। मैं क्या यह Firfebug/Chrome डेवलपर टूल का उपयोग करता है पर देखा है और वह काफी आसान लगता है:कोड

पोस्ट "usrname = $ उपयोगकर्ता & पास = $ पास & nopass_email = प्रकार + में + अपने + ई-मेल + और + प्रेस + & nopass = 0 "वेबपृष्ठ पर" http://wallbase.cc/user/login "दर्ज करें, लौटाई गई कुकीज़ संग्रहीत करें और भविष्य के सभी अनुरोधों पर उनका उपयोग करें।

private CookieContainer _cookies = new CookieContainer(); 

    //...... 

    HttpPost("http://wallbase.cc/user/login", string.Format("usrname={0}&pass={1}&nopass_email=Type+in+your+e-mail+and+press+enter&nopass=0", Username, assword)); 

    //...... 


    private string HttpPost(string url, string parameters) 
    { 
     try 
     { 
      System.Net.WebRequest req = System.Net.WebRequest.Create(url); 
      //Add these, as we're doing a POST 
      req.ContentType = "application/x-www-form-urlencoded"; 
      req.Method = "POST"; 

      ((HttpWebRequest)req).Referer = "http://wallbase.cc/home/"; 
      ((HttpWebRequest)req).CookieContainer = _cookies; 

      //We need to count how many bytes we're sending. Post'ed Faked Forms should be name=value& 
      byte[] bytes = System.Text.Encoding.ASCII.GetBytes(parameters); 
      req.ContentLength = bytes.Length; 
      System.IO.Stream os = req.GetRequestStream(); 
      os.Write(bytes, 0, bytes.Length); //Push it out there 
      os.Close(); 

      //get response 
      using (System.Net.WebResponse resp = req.GetResponse()) 
      { 

       if (resp == null) return null; 
       using (Stream st = resp.GetResponseStream()) 
       { 
        System.IO.StreamReader sr = new System.IO.StreamReader(st); 
        return sr.ReadToEnd().Trim(); 
       } 
      } 
     } 
     catch (Exception) 
     { 
      return null; 
     } 
    } 

अपना लॉगिन मानकों के साथ HttpPost कॉल करने के बाद मैं भविष्य में इस एक ही विधि का उपयोग कर कॉल प्रमाणीकृत किया की उम्मीद करेंगे (एक वैध उपयोगकर्ता नाम/पासवर्ड कल्पना करते हुए):

यहाँ मेरी कोड है। मुझे अपने कुकी संग्रह में एक सत्र कुकी मिलती है लेकिन किसी कारण से मुझे प्रमाणित नहीं किया जाता है। मुझे अपने कुकी संग्रह में एक सत्र कुकी मिलती है, भले ही मैं किस पृष्ठ पर जाता हूं, इसलिए मैंने शुरुआती सत्र कुकी प्राप्त करने के लिए पहले होम पेज लोड करने का प्रयास किया और फिर लॉग इन किया लेकिन इसमें कोई बदलाव नहीं आया। https://github.com/sevensins/Wallbase-Downloader/blob/master/wallbase.sh (लाइन 336)

कैसे काम कर प्रमाणीकरण प्राप्त करने के लिए पर कोई भी विचार:

मेरी जानकारी के लिए इस अजगर संस्करण में काम करता है

?

अद्यतन # 1
जब एक सही उपयोगकर्ता/पासवर्ड युग्म प्रतिक्रिया स्वचालित रूप से रेफरर पर रीडायरेक्ट लेकिन एक गलत उपयोगकर्ता/पास जोड़ी प्राप्त होता है जब यह रीडायरेक्ट नहीं करता है और एक बुरा उपयोगकर्ता/पास जोड़ी देता है का उपयोग कर। इस पर आधारित ऐसा लगता है कि प्रमाणीकरण हो रहा है, लेकिन शायद जानकारी के सभी महत्वपूर्ण टुकड़े सहेजे नहीं जा रहे हैं ??

अद्यतन # 2

मैं .NET 3.5 उपयोग कर रहा हूँ। जब मैंने उपरोक्त कोड को .NET 4 में कोशिश की, System.Net.ServicePointManager.Expect100Continue = false (जो मेरे कोड में था, बस यहां नहीं दिखाया गया) की अतिरिक्त पंक्ति के साथ यह काम करता है, कोई बदलाव आवश्यक नहीं है। समस्या कुछ पूर्व- नेट 4 मुद्दे से सीधे लगती है।

+0

आपको यह सुनिश्चित करने की ज़रूरत है कि आप 'प्रतिक्रिया' को बंद/निपटान करें - या इसे '() 'ब्लॉक में डाल दें। क्या आप बाद के अनुरोधों पर एक ही कुकी कंटेनर का पुन: उपयोग कर रहे हैं? – debracey

+0

@debracey: मैं एक ही कुकी कंटेनर का उपयोग कर रहा हूं, कुकी कंटेनर एक वर्ग स्तर का निजी चर है जिसे प्रत्येक एचटीपीपोस्ट के लिए पुन: उपयोग किया जाता है। मैंने ब्लॉकों का उपयोग करने के लिए अपने कोड को ट्वीक किया और मेरे प्रश्न में कोड अपडेट किया, कोई बदलाव नहीं। – Peter

उत्तर

6

यह मेरा परियोजनाओं में से एक से कोड है, साथ ही कोड stackoverflow को यहां विभिन्न जवाब से पाया पर आधारित है।

सबसे पहले हमें Cookie aware WebClient सेट करने की आवश्यकता है जो HTML 1.0 का उपयोग करने जा रहा है।

public class CookieAwareWebClient : WebClient 
{ 
    private CookieContainer cookie = new CookieContainer(); 

    protected override WebRequest GetWebRequest(Uri address) 
    { 
     HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address); 
     request.ProtocolVersion = HttpVersion.Version10; 
     if (request is HttpWebRequest) 
     { 
      (request as HttpWebRequest).CookieContainer = cookie; 
     } 
     return request; 
    } 
} 

अगला हम कोड है कि Authentication संभालती है और फिर अंत में response लोड करता है की स्थापना की।

var client = new CookieAwareWebClient(); 
client.UseDefaultCredentials = true; 
client.BaseAddress = @"http://wallbase.cc"; 

var loginData = new NameValueCollection(); 
loginData.Add("usrname", "test"); 
loginData.Add("pass", "123"); 
loginData.Add("nopass_email", "Type in your e-mail and press enter"); 
loginData.Add("nopass", "0"); 
var result = client.UploadValues(@"http://wallbase.cc/user/login", "POST", loginData); 

string response = System.Text.Encoding.UTF8.GetString(result); 

हम इस बाहर HTML Visualizer इनबिल्ट का उपयोग कर Visual Studio में जबकि डिबग मोड में रह कोशिश करते हैं और उपयोग करें कि पुष्टि करते हैं कि हम authenticate करने में सक्षम थे और लोड होम पेज जबकि authenticated रहने के लिए कर सकते हैं।

Success

कुंजी यहाँ 1.1 के बजाय एक CookieContainer की स्थापना की और HTTP 1.0 उपयोग करने के लिए, है। मुझे पूरी तरह से यकीन नहीं है कि इसे 1.0 का उपयोग करने के लिए मजबूर क्यों किया जाता है, जिससे आप पृष्ठ को सफलतापूर्वक प्रमाणित और लोड कर सकते हैं, लेकिन समाधान का हिस्सा इस उत्तर पर आधारित है। https://stackoverflow.com/a/10916014/408182

मुझे यकीन है कि प्रतिक्रिया C# Client द्वारा भेजे गए अपने वेब ब्राउज़र Chrome साथ के रूप में ही था बनाने के लिए Fiddler इस्तेमाल किया। यह मुझे पुष्टि करने की अनुमति देता है कि C# client सही तरीके से रीडायरेक्ट किया जा रहा है या नहीं। इस मामले में हम देख सकते हैं कि HTML 1.0 के साथ हमें HTTP/1.0 302 Found मिल रहा है और फिर हमें इच्छित रूप से होम पेज पर रीडायरेक्ट कर रहा है। अगर हम HTML 1.1 पर वापस स्विच करते हैं तो हमें इसके बजाय HTTP/1.1 417 Expectation Failed message मिल जाएगा। Fiddler

इस स्टैक ओवरफ्लो थ्रेड में उपलब्ध इस त्रुटि संदेश पर कुछ जानकारी है। HTTP POST Returns Error: 417 "Expectation Failed."

संपादित करें: हैक/फिक्स .NET 3.5

के लिए मैं बहुत समय बिताया है 3.5 और 4.0 के बीच अंतर पता लगाने की कोशिश, लेकिन मैं गंभीरता से कोई सुराग नहीं है। ऐसा लगता है कि 3.5 प्रमाणीकरण के बाद एक नई कुकी बना रहा है और इसके आसपास मुझे मिला एकमात्र तरीका उपयोगकर्ता को दो बार प्रमाणीकृत करना था।

मुझे इस पोस्ट से जानकारी के आधार पर वेब क्लाइंट पर कुछ बदलाव करना पड़ा। http://dot-net-expertise.blogspot.fr/2009/10/cookiecontainer-domain-handling-bug-fix.html

public class CookieAwareWebClient : WebClient 
{ 
    public CookieContainer cookies = new CookieContainer(); 
    protected override WebRequest GetWebRequest(Uri address) 
    { 
     var request = base.GetWebRequest(address); 
     var httpRequest = request as HttpWebRequest; 
     if (httpRequest != null) 
     { 
      httpRequest.ProtocolVersion = HttpVersion.Version10; 
      httpRequest.CookieContainer = cookies; 

      var table = (Hashtable)cookies.GetType().InvokeMember("m_domainTable", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.Instance, null, cookies, new object[] { }); 
      var keys = new ArrayList(table.Keys); 
      foreach (var key in keys) 
      { 
       var newKey = (key as string).Substring(1); 
       table[newKey] = table[key]; 
      } 
     } 
     return request; 
    } 
} 

var client = new CookieAwareWebClient(); 

var loginData = new NameValueCollection(); 
loginData.Add("usrname", "test"); 
loginData.Add("pass", "123"); 
loginData.Add("nopass_email", "Type in your e-mail and press enter"); 
loginData.Add("nopass", "0"); 

// Hack: Authenticate the user twice! 
client.UploadValues(@"http://wallbase.cc/user/login", "POST", loginData); 
var result = client.UploadValues(@"http://wallbase.cc/user/login", "POST", loginData); 

string response = System.Text.Encoding.UTF8.GetString(result); 
+0

आपने यह कैसे सत्यापित किया कि यह काम कर रहा था? जब मैं इस कोड को चलाता हूं तो मुझे लगता है "अरे बेनामी!" प्रतिक्रिया में, और मैं लॉग इन नहीं हूँ। – Peter

+0

हाँ, मुझे वही मिल रहा है और यही कारण है कि मैंने पहले अपना जवाब अपडेट किया था। मैं जल्द ही अपना जवाब अपडेट करूंगा। – eandersson

+0

@ पीटर ठीक है, उत्तर अपडेट किया गया। कोड 'उपयोगकर्ता नाम' => 'usrname' में मेरा एक प्रमुख टाइपो था। साथ ही, 'कुकीएवेयर वेब क्लाइंट' फ़ंक्शन को अपडेट करना सुनिश्चित करें क्योंकि मैंने इसे भी अपडेट किया है। – eandersson

3

आप निम्न जोड़ने की जरूरत हो सकता है:

//get response 
using (System.Net.WebResponse resp = req.GetResponse()) 
{ 
    foreach (Cookie c in resp.Cookies) 
     _cookies.Add(c); 
    // Do other stuff with response.... 
} 

एक और बात आप क्या करना है हो सकता है कि, अगर सर्वर एक 302 (अनुप्रेषित) नेट वेब अनुरोध स्वचालित रूप से इसे और में पालन करेंगे के साथ प्रतिक्रिया है जिस प्रक्रिया में आप कुकी कर सकते हैं वह हो सकता है। आप नीचे दिए गए कोड के साथ इस व्यवहार को बंद कर सकते हैं:

req.AllowAutoRedirect = false; 
+0

जब मैं कुकीज़ को मैन्युअल रूप से जोड़ने का प्रयास करता हूं तो ऐसा लगता है कि वे पहले से ही वहां हैं, या वहां पर केवल ओवरराइट हो गए हैं (या तो कुकी गिनती पहले और बाद में समान रहता है)। यह एक रीडायरेक्ट कर रहा है और मैंने AllowAutoRedirect ध्वज को सही/गलत पर कोड के साथ और बिना कोशिश की है लेकिन यह कुछ भी नहीं बदलेगा। – Peter

+0

फिडलर (http://www.fiddler2.com/fiddler2/) चलाने का प्रयास करते समय यह देखने के लिए कि कुकीज़ वास्तव में सेट की जा रही हैं या नहीं। प्रॉक्सी का उपयोग करने के लिए आपको अपना कोड बताना होगा। आप 'req.Proxy = new webProxy ("127.0.0.1", 8888) को कॉल करके ऐसा कर सकते हैं;' – SynXsiS

2

अजगर आप संदर्भ एक अलग संदर्भ देने वाली (http://wallbase.cc/start/) का उपयोग करता है। इसके बाद एक और पोस्ट (http://wallbase.cc/user/adult_confirm/1) भी है। इस पोस्ट के साथ अन्य रेफरर और फॉलोअप आज़माएं।

मुझे लगता है कि आप सही तरीके से प्रमाणीकरण कर रहे हैं, लेकिन आगे बढ़ने से पहले साइट को आपके से अधिक जानकारी/दावे की आवश्यकता है।

+0

http://wallbase.cc/user/adult_confirm/1 का उपयोग यह पुष्टि करने के लिए किया जाता है कि आप कार्य प्रकार के वॉलपेपर के लिए गैर-सुरक्षित देखना चाहते हैं। यदि आप फिडलर या क्रोम डेवलपर व्यू जैसे टूल का उपयोग करते हैं तो आप देखेंगे कि यह यूआरएल प्रमाणीकरण प्रक्रिया के दौरान कभी नहीं मारा जाता है। मैं इसे वैकल्पिक रेफरर के साथ आज़माउंगा, लेकिन मुझे पूरा यकीन है कि उपयोग/प्रारंभ/पुराना है और मैंने इसे पहले ही कोशिश कर लिया है। – Peter