Melden Sie sich bei der Website in C# an

Syed Hassan Sabeeh Kazmi 12 Oktober 2023
  1. Verwenden Sie den WebClient, um sich bei einer Website in C# anzumelden
  2. Schreiben Sie ein Skript zum Einloggen in eine Website in C#
  3. Erstellen Sie ein Skript zur Automatisierung von Selenium, um sich bei einer Website in C# anzumelden
  4. Verwenden Sie den HttpClient, um sich bei einer Website in C# anzumelden
Melden Sie sich bei der Website in C# an

In diesem Tutorial lernen und verstehen Sie die optimierten Methoden zur programmgesteuerten Anmeldung bei der Website in C#. Es ist möglich, sich mit ASP.NET C# automatisch bei der externen Website anzumelden, und falls die Website HTTP POST verwendet, um die Anmeldung zu validieren, können Sie die post-Methode extern verwenden.

Dies ist eine allgemeine Methode zum Hinzufügen der Dienstreferenz zum C#-Projekt, da Visual Studio automatisch einen Proxy für Sie generiert, indem die Methode proxy class web server aufgerufen wird. Programmatisch ist jedoch die perfekte Möglichkeit, einen Webserver aufzurufen und zu authentifizieren.

Verwenden Sie den WebClient, um sich bei einer Website in C# anzumelden

Der beste Ansatz für die programmgesteuerte Anmeldung auf einer Website ist die Verwendung von WebClient zu POST. Ein solider Ersatz für POST (da es für Einsteiger-Entwickler sehr komplex ist) sind die untergeordneten Klassen WebRequest und WebResponse.

Das Erstellen eines Anmeldeformulars ist einer der beiden Hauptbestandteile dieses Ansatzes, und der zweite besteht darin, den Set-cookie-Header mithilfe der GET-Anforderung wiederherzustellen. Wenn Ihr Set-cookie-Header als Cookie, den Sie zusammen mit der GET-Anfrage gesendet haben, vom antwortenden Server erkannt wird, identifiziert er Sie von nun an nur noch, wenn der Server eine Cookie-basierte Authentifizierung verwendet.

Verwenden Sie für GET folgenden C#-Code:

public static string HttpGet(string web_URI) {
  System.Net.WebRequest web_request = System.Net.WebRequest.Create(web_URI);

  // the following means no proxy for the website
  web_request.Proxy = new System.Net.WebProxy(ProxyString, true);

  System.Net.WebResponse web_response = web_request.GetResponse();

  System.IO.StreamReader stream_reader =
      new System.IO.StreamReader(web_response.GetResponseStream());

  return stream_reader.ReadToEnd().Trim();
}

Verwenden Sie den folgenden C#-Code für SET:

public static string HttpPost(string web_URI, string web_para) {
  System.Net.WebRequest web_request = System.Net.WebRequest.Create(web_URI);
  web_request.Proxy = new System.Net.WebProxy(ProxyString, true);

  // add the following as you are doing the `POST`
  web_request.ContentType = "your_application/insert-the-form-rncoded-URL";
  web_request.Method = "POST";  // SET

  // it's important to know how many bytes you are transforming or sending to the server.
  // Remember | Post'ed Faked Forms should be `name=value&`
  byte[] sending_bytes = System.Text.Encoding.ASCII.GetBytes(web_para);
  web_request.ContentLength = sending_bytes.Length;

  System.IO.Stream web_stream = web_request.GetRequestStream();

  // you can push the bytes here
  web_stream.Write(sending_bytes, 0, sending_bytes.Length);
  web_stream.Close();

  System.Net.WebResponse web_response = web_request.GetResponse();
  if (web_response == null)
    return null;

  System.IO.StreamReader stream_reader =
      new System.IO.StreamReader(web_response.GetResponseStream());

  return stream_reader.ReadToEnd().Trim();
}

Formularbeiträge sind einfach zu simulieren, da Sie Ihre Beitragsdaten einfach formatieren können, indem Sie Folgendes tun:

field_1 = value_1 & field_2 = value_2

Der C#-Beispielcode WebClient dieser Methode spiegelt den Ansatz von Scott Hanselman wider, sich mit WebRequest bei einer Website anzumelden.

Darüber hinaus repräsentiert der folgende C#-Code den von Scott Hanselman entwickelten Ansatz zur programmgesteuerten Anmeldung bei Websites:

// the `web_URL` represents the `POST` URL instead of the `form` URL
// to access `form` URL, find the `action` attribute of the HTML's `form` tag
string web_URL =
    "http://www.examplewebsite.com/index.do?PageModule=UserAccess&Modification=UsersVerificationviaLogin";

string parameter_form = string.Format("example_format(email_address={0}&password={1})",
                                      "my_email_address", "my_password");

// create a header cookie
string header_cookie;

// create a request object from the `WebRequest`
WebRequest web_request = WebRequest.Create(web_URL);

// define its content type and method
web_request.ContentType =
    "yourC#application/x-www_address-form-encoded_url";  // or something like
                                                         // "application/x-www-form-urlencoded"
web_request.Method = "POST";  // as it's a request, so the method will be POST

// access the `parameter_form` to convert it into bytes (sending it to the server)
byte[] sending_bytes = Encoding.ASCII.GetBytes(parameter_form);
web_request.ContentLength = sending_bytes.Length;  // define its length

using (Stream web_stream = web_request.GetRequestStream()) {
  // for web requests or requests to the server for login
  web_stream.Write(sending_bytes, 0, sending_bytes.Length);
}

// create a `WebResponse` object to receive or understand the response from the corresponding server
WebResponse web_response = web_request.GetResponse();
header_cookie = web_response.Headers["Set-cookie"];  // `Set-cookie` as a web response header file

/*
    GET
*/

// define a source page and the `GET` web URL
string source_page;
string web_URL_get =
    "http://www.webpage_behind_the_login.com";  // mention the webpage behind the login form

// create a GET response
WebRequest web_request_get = WebRequest.Create(web_URL_get);
web_request_get.Headers.Add("Cookie", header_cookie);

// web_request_get.ContentLength = web_request.ContentLength;
WebResponse web_response_get = web_request_get.GetResponse();

using (StreamReader stream_reader_get = new StreamReader(web_response_get.GetResponseStream())) {
  source_page = stream_reader_get.ReadToEnd();
}

Das Folgende ist der C#-Code, den Sie in Ihr C#-Projekt kopieren/einfügen und sich mit WebClient bei einer Website anmelden können. Denken Sie jedoch daran, Ihren eigenen Benutzernamen und Ihr eigenes Passwort zu verwenden und die Website-URL einzugeben. Vergessen Sie auch nicht, die Webseite zu erwähnen, auf die Ihr C#-Programm Sie nach einer erfolgreichen Anmeldung umleitet.

using System;
using System.Windows.Forms;
using System.Net;
// using System.Net.Http;
using System.Collections.Specialized;

namespace test_login {
  // create a sub-class using `WebClient`
  public class CookieAwareWebClient : WebClient {
    // create a cookie container for web requests and web response
    private CookieContainer website_cookie = new CookieContainer();

    // overload using URI of the target web address
    protected override WebRequest GetWebRequest(Uri trg_web_add) {
      WebRequest tag_web_request = base.GetWebRequest(trg_web_add);
      if (tag_web_request is HttpWebRequest) {
        (tag_web_request as HttpWebRequest).CookieContainer =
            website_cookie;  // generate a proper request to the server
      }
      return tag_web_request;
    }
  }
  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e) {
      // create a new user
      var new_user = new CookieAwareWebClient();

      // base address of the corresponding webpage (for login)
      new_user.BaseAddress = @"https://www.example_website/some_page/login/url_address/";

      // create a variable that carries the user information
      var user_info = new NameValueCollection();
      user_info.Add("username", "your_username");  // username or mail address
      user_info.Add("password", "your_password");  // password

      // upload the user information to the webpage
      new_user.UploadValues("login_page.php", "POST", user_info);

      // successfully login can request the pages, following
      string source_html = new_user.DownloadString("website_homepage.php");
    }
  }
}

Ausgang:

username: your_username
password: your_password

[redirect the user to the `index.php` after a successful login]

Eine weitere interessante Idee besteht darin, diesen Ansatz zu modifizieren, indem ein CookieContainer-Objekt auf die GetWebRequest-Methode gesetzt wird, nachdem es überschrieben wurde, indem eine Klasse erstellt wird, die von WebClient abgeleitet ist. Standardmäßig kann eine einzige oder dieselbe CookieContainer-Instanz die Cookie-Verwaltung übernehmen.

Schreiben Sie ein Skript zum Einloggen in eine Website in C#

Das Anmeldeverfahren für jede Website kann einzigartig sein und erfordert unterschiedliche Protokolle, da das programmgesteuerte Anmelden bei Websites eng damit gekoppelt ist, wie die Websites ihre Anmeldeverfahren implementieren. Sie müssen den Prozess verstehen und Ihre Anfragen und Antworten (an und vom Server) entsprechend schreiben.

Das Schreiben eines unglaublich komplizierten und fragilen Skripts zum Bestehen der Website-Prozeduren ist keine leichte Aufgabe, aber dies kann die Sicherheit und Effektivität Ihrer Anwendung verbessern. Außerdem kann es hilfreich sein, AllowAutoRedirect auszuschalten und sowohl POST- als auch GET-Anfragen auf denselben Benutzeragenten zu setzen, indem Sie so etwas tun:

request.UserAgent = UserAgent;

// to eliminate any redirection to other website or webpage
request.AllowAutoRedirect = false;

Einige Websites senden kryptische URL-codierte Rückgabewerte, wenn Sie versuchen, sich anzumelden, und wenn der Server bemerkt, dass etwas fehlt, wirft er etwas wie HTTP/1.1 400 Bad Request, oder es kann eine 200-Antwort vom Server mit einem sein Fehlermeldung irgendwo im Inneren vergraben. Sie müssen die richtigen Werte sammeln und sie in einem HttpWebRequest-Objekt übergeben, damit der Server den Unterschied nicht erkennt und Sie sich anmelden lässt.

using System;
using System.Windows.Forms;
using System.Net;
// using System.Net.Http;
using System.IO;
// using System.Collections.Specialized;

namespace test_login {
  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e) {
      string user_name = UsernameBox.Username;              // textbox that contains the user name
      string user_password = PasswordBoxPassword.Password;  // textbox that contains the password

      // HTML IDs or important user information to perform a successful login against a specific
      // user
      string login_user_name = textBox1.Text;      // username
      string login_user_password = textBox2.Text;  // password

      // submit info for a successful login
      string login_submit_info = textBox3.Text;  // login submit

      // define the website or webpage connection parameters
      string post_method = "POST";  // `POST` method for web_request
      string type_webcontent = @"c_sharp-application/encoded_url-www-form";
      string string_login = login_user_name + "=" + user_name + "&" + login_user_password + "=" +
                            user_password + "&" + login_submit_info;
      CookieContainer container_cookie = new CookieContainer();
      HttpWebRequest web_request;

      web_request = (HttpWebRequest)WebRequest.Create(
          "http://www.example_url.com/login_page/");  // or insert the `url` string that contains
                                                      // the valid website URL
      web_request.CookieContainer = container_cookie;
      web_request.Method = post_method;  // for web request
      web_request.ContentType = type_webcontent;
      web_request.KeepAlive = true;

      using (Stream web_stream_request = web_request.GetRequestStream())

          // generate a proper web request
          using (StreamWriter writer = new StreamWriter(web_stream_request)) {
        writer.Write(string_login, user_name, user_password);
      }

      using (var web_stream_response = web_request.GetResponse().GetResponseStream()) using (
          var web_response_reader = new StreamReader(web_stream_response)) {
        var user_check = web_response_reader.ReadToEnd();
        Console.WriteLine(user_check);  // the result
      }

      MessageBox.Show("Successful login to website!");
    }
  }
}

Ausgang:

Successful login to website!

Erstellen Sie ein Skript zur Automatisierung von Selenium, um sich bei einer Website in C# anzumelden

Da das Schreiben eines manuellen Skripts frustrierend sein kann, kann das Erstellen eines Skripts zur Automatisierung von selenium.WebDriver eine gültige Option sein, um sich programmgesteuert bei einer Website in C# anzumelden. Es ermöglicht Ihnen, Ihre Anfragen normal zu werfen, indem Sie das ganze Jonglieren erledigen, damit Sie gültige Cookies herausziehen können.

Es ist wichtig, selenium zu verstehen, um Ihren Code zu optimieren; Beispielsweise funktioniert es hervorragend, um sich bei azure anzumelden, um Credits zu erhalten, was das Schreiben von Skripten unglaublich kurz macht. Da jedoch der CookieContainer exp_cookie = new CookieContainer(); fehlt was bedeutet, dass es nicht für Website-Unterstützungen CookieContainer geeignet ist.

// Install `Selenium.WebDriver` NuGet Package
// Install `Selenium.WebDriver.ChromeDriver` NuGet Package

using System;
using System.Windows.Forms;
using System.Net;
// using System.Net.Http;
using System.IO;
// using System.Collections.Specialized;

using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;

namespace login_website {
  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
    }
    private void button1_Click(object sender, EventArgs e) {
      // run selenium | starts from...
      ChromeDriver chrome_driver = new ChromeDriver(
          @"chromedriver_win32");  // install the selenium chrome web driver for `ChromeDriver`
      chrome_driver.Url = @"https://fif.com/login";
      chrome_driver.Navigate();
      IWebElement web_element = chrome_driver.FindElementById(
          "user_name");  // install selenium web driver to use `FindElementById()` method
      web_element.SendKeys("...");
      web_element = chrome_driver.FindElementById("user_password");
      web_element.SendKeys("...");
      web_element = chrome_driver.FindElementByXPath(
          @"//*[@id=""main""]/div/div/div[2]/table/tbody/tr/td[1]/div/form/fieldset/table/tbody/tr[6]/td/button");
      web_element.Click();

      CookieContainer cookie_container = new CookieContainer();

      // get the cookies from the website
      foreach (OpenQA.Selenium.Cookie web_cookie in chrome_driver.Manage().Cookies.AllCookies) {
        string user_name = web_cookie.Name;
        string user_value = web_cookie.Value;
        cookie_container.Add(
            new System.Net.Cookie(user_name, user_value, web_cookie.Path, web_cookie.Domain));
      }

      // generate a proper web request
      HttpWebRequest http_web_request = (HttpWebRequest)HttpWebRequest.Create(
          "https://example.com/web_content/com_example/web_tools/page_capacity/login_values/");  // or something like "https://fif.com/components/com_fif/tools/capacity/values/"
      http_web_request.CookieContainer = cookie_container;
      http_web_request.Method = "POST";
      http_web_request.ContentType = "application/x-www-form-urlencoded";

      StreamWriter stream_writer = new StreamWriter(http_web_request.GetRequestStream());
      stream_writer.Write("feeds=35");
      stream_writer.Close();

      WebResponse web_response = http_web_request.GetResponse();
      string response_imp =
          new System.IO.StreamReader(web_response.GetResponseStream()).ReadToEnd();
    }
  }
}

Ausgang:

[redirect the user to the `index.php` after a successful login]

* or

[shows an error for wrong username or password for invalid user]

Es ist kein Selenium-Server erforderlich, um den Browser zu automatisieren. Es umgeht die JavaScript-Sandbox, indem es native Ereignisse auf Betriebssystemebene verwendet, um den Browser zu manipulieren.

Zudem enthält es die .NET Bindings für die übersichtliche und objektbasierte Selenium WebDriver API.

Selenium bietet ein Bündel verschiedener Softwaretools, jedes mit einem anderen Ansatz zur Unterstützung der Browserautomatisierung. Es bietet hochflexible Tools zum Auffinden und Bearbeiten von Elementen in einem Browser und unterstützt die Automatisierung für mehrere Browserplattformen.

Verwenden Sie den HttpClient, um sich bei einer Website in C# anzumelden

Es kann Ihnen helfen, auf die eigentliche Anmeldeantwort zuzugreifen, da der Statuscode für die Weiterleitung 3** lautet; Sie müssen die Umleitung mit HttpClient deaktivieren. Senden Sie die Anmeldeinformationen zum Anfordern der URL mit der Anforderungsmethode HTTP verb (in den meisten Fällen kann es die Methode POST sein).

Es ist immer einfach, eine Anmeldemethode basierend auf den Cookies zu implementieren, die der Server vom angemeldeten Benutzer erwartet, und diese Informationen basieren auf den Daten, die der Header set-cookie enthält.

Sie können die Methoden GET und POST in HttpClient verwenden, um sich auf einer Website anzumelden, da das GET keinen HTTP-Body enthält. Bei einem POST wandern die Daten aus dem QueryString in den HTTP-Body.

Die Benutzeranmeldeinformationen oder die Daten, die Sie übergeben, werden über Parameter übergeben, und der Rest ist fest codiert. Am wichtigsten ist, dass die Schlüssel-Wert-Paar-Instanz (KeyValuePair<string, string>) die angegebene Sequenz von Formulardaten darstellt, die Ihnen helfen können, sich programmgesteuert bei der Website anzumelden.

Manchmal kann es vorkommen, dass nur benutzerspezifische Daten erforderlich sind, und es ist ein wesentlicher Schritt für Sie, die Website anzufordern und HTML mit AngleSharp oder einer ähnlichen Methode zu analysieren, wenn die Website von Ihnen verlangt, dass Sie versteckte Felder von der Anmeldeseite einfügen.

Abschließend wird die resultierende Sequenz mit Schlüsseln und Werten (Nullable-Strings) an den Konstruktor FormUrlEncodedContent übergeben (er erwartet, dass die Schlüssel und Werte der Sequenz Nullable-Strings sind).

// try not to change the entry point of this C# code
// it's important to remember that the `website_login.Program.Main` in your C# project is the entry
// point of this C# program. changing the entry point can lead to many difficulties and logical or
// syntax errors

using System;
using System.Net;
using System.IO;

namespace website_login {
  public class Program {
    public static void Main(string[] args) {
      var add_primary = new Uri("https://www.example_website.com/");
      var container_cookie = new CookieContainer();  // for web request

      // generate a proper web request | special HTTP implementation of the `WebRequest` class
      HttpWebRequest post_request_web =
          (HttpWebRequest)HttpWebRequest.Create("https://www.example_website.com/");
      post_request_web.CookieContainer = container_cookie;

      /*
       * setting the agent (user_agent) and accepting the header values
       * these are important to simulate a real web browser
       */
      post_request_web.UserAgent =
          "Chrome/5.3 (Windows Professional 11.2; WOW32) Chrome/45.0.2454.101";  // change it with
                                                                                 // respect to your
                                                                                 // platform, OS,
                                                                                 // and browser
      post_request_web.Accept =
          "text_type/html,c_sharp_application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";  // set values

      Console.WriteLine("[response from the server...]");
      Console.WriteLine();

      // generate a proper web response
      using (WebResponse get_response_web = post_request_web.GetResponse()) {
        // to read the response from the web server
        using (StreamReader stream_reader =
                   new StreamReader(get_response_web.GetResponseStream())) {
          Console.WriteLine(stream_reader.ReadToEnd());  // display
        }
      }

      post_request_web = (HttpWebRequest)HttpWebRequest.Create("https://www.example_website.com/");

      // setting `container_cookie` as a cookie container object
      post_request_web.CookieContainer = container_cookie;

      post_request_web.UserAgent =
          "Chrome/5.3 (Windows Professional 11.2; WOW32) Chrome/45.0.2454.101";  // change it with
                                                                                 // respect to your
                                                                                 // platform, OS,
                                                                                 // and browser
      post_request_web.Accept =
          "text_type/html,c_sharp_application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";  // set values

      post_request_web.Method = "POST";  // POST method because of web request
      post_request_web.ContentType =
          "application/x-www-form-urlencoded";  // it is a standard content type

      // the `user_infomration` variable contains the username and password of a user for login
      string user_information =
          string.Format("username={0}&password={1}", "your_username", "your_password");

      // encode the user information to send it to the web server
      byte[] _web_bytes = System.Text.Encoding.UTF8.GetBytes(user_information);

      post_request_web.ContentLength = _web_bytes.Length;

      using (Stream web_stream_user_info = post_request_web.GetRequestStream()) {
        web_stream_user_info.Write(_web_bytes, 0, _web_bytes.Length);
        web_stream_user_info.Close();
      }

      Console.WriteLine("[response form the server on user login...]");
      Console.WriteLine();

      using (WebResponse web_response_dll = post_request_web.GetResponse()) {
        // to read the response from the web server
        using (StreamReader stream_reader_dll =
                   new StreamReader(web_response_dll.GetResponseStream())) {
          Console.WriteLine(stream_reader_dll.ReadToEnd());  // display
        }
      }

      //....
    }
  }
}

Ausgang:

[response from the server...]

... // some response from the website
*response from the `streamreader`*

[response from the server on user login...]
// response from the server or website after the first login attempt

Die Instanz des Konstruktors FormUrlEncodedContent ist der primäre Inhalt der POST-Anforderung im PostAsync-Aufruf, und nach diesem Aufruf besteht der nächste Schritt darin, die set-cookie-Header aus der HTTP-Antwort zu analysieren. Es ist immer schwierig, ein gutes NuGet-Paket in der .NET-Klassenbibliothek zu finden, und deshalb ist die Analyse mithilfe eines regulären Ausdrucks der bessere Weg.

Überprüfen Sie das Antwort-Cookie, um eine fehlgeschlagene Anmeldung zu erkennen, überprüfen Sie den Statuscode der Antwort vom Server oder parsen Sie den vom Server zurückgegebenen HTML-Inhalt. Das Aufrufen von LoginAsync vor dem Herunterladen der angeforderten Seite ist immer eine gute Option, um die Anmelde-Cookies abzurufen oder zurückzugeben, damit Sie sie für die Anfrage an den Server verwenden können.

Wenn Sie keine eingebaute GetStringAsync-Methodenüberladung mit einem Parameter für Cookies finden, erstellen Sie selbst eine Erweiterungsmethode, wie Sie deren Erstellung im folgenden C#-Code beobachten werden. Bevor Sie die Methode SendAsync zum Senden der Anfrage (generierter HTTP-Request) verwenden, müssen Sie alle Cookies in einem einzigen cookie-Header zusammenfassen.

Es ist eine Option, wenn Sie die automatische Umleitungsfunktion des HttpClient deaktivieren möchten, wenn der Statuscode der Anmeldeantwort eine Umleitung erfordert. Dies kann mit der Instanz HttpClient erfolgen, da dies mit der IHttpClientFactory möglich ist, indem die Option bei der Registrierung des HttpClient für die Abhängigkeitsinjektion übergeben wird.

Da es in HttpClient oder .NET im Allgemeinen keine integrierte Funktionalität gibt, um sich programmgesteuert bei einer Website anzumelden, müssen Sie alle Schritte manuell ausführen, und es kann möglich sein, dass der Vorgang jedes Mal anders ist. Da die Authentifizierungs- bzw. Anmeldedaten auf einem Cookie abgelegt werden, stellen Sie den CookieContainer ein, um eine Anmeldung auf einer Standard-FormsAuthentication-Webseite mit dem HttpClient durchzuführen.

Syed Hassan Sabeeh Kazmi avatar Syed Hassan Sabeeh Kazmi avatar

Hassan is a Software Engineer with a well-developed set of programming skills. He uses his knowledge and writing capabilities to produce interesting-to-read technical articles.

GitHub

Verwandter Artikel - Csharp Authentication