Logowanie do strony internetowej wpf

0

Witam wszystkich,

Na początku chciałbym napisać ,że nigdy nie bawiłem się w łącznie aplikacji pisanych w c# z stronami internetowymi, natomiast znam podstawy tego języka. Mój problem jest następujący podjąłem się w ramach czysto ćwiczeniowych napisania aplikacji planu lekcji dla mojej uczelni. Niestety mimo ,że strona mojej Politechnika posiada system usos to nie ma dla niej api. I stąd pomysł aby plan wziąć z logowania na stronę internetową. Niestety mimo wielu prób i szukania informacji nie jestem w stanie się zalogować. Podejrzewa ,że problem leży w tym ,że nie do końca rozumiem kod którego używam i tym ,że logowanie do tej strony jest nieco inne bo w ciasteczku jest dodatkowo numer randomowo losowany ,który łatwo wyciągnąć z kodu strony.


      void pobierz(string login, string password)
      {
          string formUrl = "https://cas.po.edu.pl/login";
          
          string cookieHeader;
          string pageSourceFirst;
          WebRequest req = WebRequest.Create(formUrl);
          WebResponse getResponse1 = req.GetResponse();
          using (StreamReader sr = new StreamReader(getResponse1.GetResponseStream()))
          {
              pageSourceFirst = sr.ReadToEnd();
          }
          int pozycja = pageSourceFirst.IndexOf("name=\"lt\"");
          int i= pozycja + 17;
          bool test= true;
          string LT="";
          while (test)
          {
              if (pageSourceFirst[i] == '"')
              {
                  test = false;
              }
              else
              {
                  LT += pageSourceFirst[i];
              }
              i++;
          }
          string formParams = string.Format("username={0}&password={1}&lt={2}&execution=e1s1&_eventId=submit&submit=ZALOGUJ", "login", "password", LT);
         
          cookieHeader = req.Headers["Set-cookie"];
          req.Headers.Add("Cookie", cookieHeader);

          req.ContentType = "application/x-www-form-urlencoded";
          req.Method = "POST";
          byte[] bytes = Encoding.ASCII.GetBytes(formParams);
          req.ContentLength = bytes.Length;
          using (Stream os = req.GetRequestStream())
          {
              os.Write(bytes, 0, bytes.Length);
          }
          WebResponse resp = req.GetResponse();
          

          string pageSource;
          string getUrl = "https://cas.po.edu.pl/login";
          WebRequest getRequest = WebRequest.Create(getUrl);
          getRequest.Headers.Add("Cookie", cookieHeader);
          WebResponse getResponse = getRequest.GetResponse();
          using (StreamReader sr = new StreamReader(getResponse.GetResponseStream()))
          {
              pageSource = sr.ReadToEnd();
          }

      }

Ten kod zwraca InvalidOperationException: Nie można ustawić tej właściwości po rozpoczęciu zapisywania.
Strona to https://cas.po.edu.pl/login
Natomiast dane ciasteczka wyglądają tak:
username=abc&password=abc&lt=LT-5175-fkXdGbKY39LoWd6wqkhDlxKKgqmTcF&execution=e1s1&_eventId=submit&submit=ZALOGUJ

Według programu Fiddler.

Chciałbym się tego nauczyć.
To mój pierwszy post tutaj z góry dziękuję za pomoc.

0

Jest też opcja, że program z poziomu C# otworzy przeglądarkę, wejdzie na stronę, wpisze login i hasło w okienko logowania i kliknie przycisk "Zaloguj'`, a następnie pobierze potrzebne dane.

Szukaj pod hasłami typu: Frontend Unit Tests lub narzędzia typu C# Selenium.

że logowanie do tej strony jest nieco inne bo w ciasteczku jest dodatkowo numer randomowo losowany

Czyżby antiforgery token?

0

Dziękuje bardzo za odpowiedź faktycznie wygląda na to o czym piszesz dlatego stwierdziłem ,że na razie spróbuje się zalogować metodą ,którą mi poleciłeś stwierdziłem ,że będę sprytny i użyję do tego WebBrowser ale nie tej z wpf tylko z WindowsForms niestety chyba próbowałem być zbyt sprytny bo niestety przy takim kodzie :

  void zaloguj()
        {
            System.Windows.Forms.WebBrowser web = new System.Windows.Forms.WebBrowser();
            web.AllowNavigation = true;
            web.Navigate(new System.Uri("https://cas.po.edu.pl/login"));
   
            string a = web.DocumentText;
            web.Document.GetElementById("username").SetAttribute("value", "login");
            web.Document.GetElementById("password").SetAttribute("value", "password");
            var inputElements = web.Document.GetElementsByTagName("input");
            foreach(HtmlElement i in inputElements)
            {
                if (i.GetAttribute("name").Equals("submit"))
                {
                    i.InvokeMember("click");
                }
            }
        }

niestety string a jest cały czas pusty (użyłem go do testu). Co zrobiłem źle?

1

title

Taki kod, na Firefoxa (możesz użyć Chrome):

Tylko musisz pobrać silnik Firefoxa i podać do niego ścieżkę - zmienna path, oraz oczywiście nugeta Selenium.WebDriver

https://github.com/mozilla/geckodriver/releases

tego execa - geckodriver-v0.24.0-win64.zip

var path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);

IWebDriver driver = new FirefoxDriver(path);

driver.Url = "https://cas.po.edu.pl/login";
driver.Navigate();

var loginBox = driver.FindElement(By.Id("username"));
var passwordBox = driver.FindElement(By.Id("password"));
var zalogujButton = driver.FindElement(By.Name("submit")); // uwaga, może być ich wiele.

loginBox.Clear();
loginBox.SendKeys("moj_login");

passwordBox.Clear();
passwordBox.SendKeys("moje_haslo");

zalogujButton.Click();
driver.Quit();

Oczywiście to tylko hello world / proof of concept. Jeżeli będziesz chciał coś bardziej zaawansowanego, to możesz nawet wstrzykiwać Javascript.

https://stackoverflow.com/questions/6229769/execute-javascript-using-selenium-webdriver-in-c-sharp

var js = (IJavaScriptExecutor)driver;
js.ExecuteScript("alert('123')");
0

@Botek:

Ok, mam, zerknij na to i poczekaj chwilę aż wypiszę na konsolę.

var path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);

FirefoxOptions firefoxOptions = new FirefoxOptions();
firefoxOptions.AddArguments("--headless");

IWebDriver driver = new FirefoxDriver(path, firefoxOptions);
         

driver.Url = "https://cas.po.edu.pl/login";
driver.Navigate();

var loginBox = driver.FindElement(By.Id("username"));
var passwordBox = driver.FindElement(By.Id("password"));
var zalogujButton = driver.FindElement(By.Name("submit")); // uwaga, może być ich wiele.

loginBox.Clear();
loginBox.SendKeys("moj_login");

passwordBox.Clear();
passwordBox.SendKeys("moje_haslo");

zalogujButton.Click();

var msg = driver.FindElement(By.Id("msg"));

Console.WriteLine(msg.Text);
driver.Quit();
Console.ReadKey();

A konsole też się ukryć :P

1 użytkowników online, w tym zalogowanych: 0, gości: 1