Iniciar sesión en el sitio web en C#

Syed Hassan Sabeeh Kazmi 12 octubre 2023
  1. Utilice el WebClient para iniciar sesión en un sitio web en C#
  2. Escribir un script para iniciar sesión en un sitio web en C#
  3. Cree un script para automatizar Selenium para iniciar sesión en un sitio web en C#
  4. Utilice HttpClient para iniciar sesión en un sitio web en C#
Iniciar sesión en el sitio web en C#

En este tutorial, aprenderá y comprenderá los métodos optimizados para iniciar sesión en el sitio web mediante programación en C#. Es posible iniciar sesión automáticamente en el sitio web externo usando ASP.NET C#, y en caso de que el sitio web use HTTP POST para validar el inicio de sesión, puede usar el método post externamente.

Es una forma general de agregar la referencia de servicio al proyecto de C#, ya que Visual Studio genera automáticamente un proxy llamando al método servidor web de clase de proxy. Sin embargo, la programación es la forma perfecta de llamar a un servidor web y autenticarlo.

Utilice el WebClient para iniciar sesión en un sitio web en C#

El mejor enfoque para el inicio de sesión programático en un sitio web es usar WebClient para POST. Un reemplazo sólido para POST (ya que es muy complejo para los desarrolladores de nivel de entrada) son las clases WebRequest y WebResponse de nivel inferior.

La creación de un formulario de inicio de sesión es una de las dos partes principales de este enfoque, y la segunda es recuperar el encabezado Set-cookie mediante la solicitud GET. Si el servidor que responde reconoce su encabezado Set-cookie como una Cookie que envió junto con la solicitud GET, entonces lo identificará de ahora en adelante solo si el servidor está utilizando una autenticación basada en cookies.

Utilice el siguiente código C# para GET:

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

Use el siguiente código C# para 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();
}

Las publicaciones de formulario son fáciles de simular, ya que puede formatear fácilmente los datos de su publicación haciendo algo como lo siguiente:

field_1 = value_1 & field_2 = value_2

El ejemplo de código C# WebClient de este método refleja el enfoque de Scott Hanselman para iniciar sesión en un sitio web utilizando WebRequest.

Además, el siguiente código C# representa el enfoque creado por Scott Hanselman para iniciar sesión en sitios web mediante programación:

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

El siguiente es el código C# que puede copiar/pegar en su proyecto C# e iniciar sesión en un sitio web utilizando WebClient. Sin embargo, recuerde usar su propio nombre de usuario y contraseña e ingrese la URL del sitio web, y no olvide mencionar la página web a la que su programa C# lo redirigirá después de un inicio de sesión exitoso.

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

Producción :

username: your_username
password: your_password

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

Otra idea interesante es modificar este enfoque configurando un objeto CookieContainer en el método GetWebRequest después de anularlo creando una clase que derive de WebClient. Una sola o la misma instancia de CookieContainer puede gestionar la gestión de cookies de forma predeterminada.

Escribir un script para iniciar sesión en un sitio web en C#

El procedimiento de inicio de sesión para cada sitio web puede ser único y requiere diferentes protocolos, ya que el inicio de sesión en los sitios web mediante programación está estrechamente relacionado con la forma en que los sitios web implementan sus procedimientos de inicio de sesión. Debe comprender el proceso y escribir sus solicitudes y respuestas (hacia y desde el servidor) en consecuencia.

Escribir un script increíblemente complicado y frágil para aprobar los procedimientos del sitio web no es un trabajo fácil, pero hacerlo puede mejorar la seguridad y la eficacia de su aplicación. Además, puede ayudar desactivar AllowAutoRedirect y configurar las solicitudes POST y GET para el mismo agente de usuario haciendo algo como:

request.UserAgent = UserAgent;

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

Algunos sitios web envían valores de retorno codificados en URL crípticos cuando intenta iniciar sesión, y si el servidor nota que falta algo, arrojará algo como “HTTP/1.1 400 Solicitud incorrecta”, o puede ser una respuesta 200 del servidor con un mensaje de error enterrado en algún lugar dentro. Debe recopilar los valores correctos y pasarlos en un objeto HttpWebRequest para que el servidor no note la diferencia y le permita iniciar sesión.

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

Producción :

Successful login to website!

Cree un script para automatizar Selenium para iniciar sesión en un sitio web en C#

Como escribir un script manual puede ser frustrante, crear un script para automatizar selenium.WebDriver puede ser una opción válida para iniciar sesión en un sitio web en C# mediante programación. Le permite enviar sus solicitudes normalmente al manejar todos los malabares para que pueda extraer cookies válidas.

Es importante comprender el selenio para optimizar su código; por ejemplo, funciona muy bien para iniciar sesión en azure para obtener créditos, lo que hace que escribir guiones sea increíblemente corto. Sin embargo, como falta el CookieContainer exp_cookie = new CookieContainer(); lo que significa que no es adecuado para soportes de sitios web CookieContainer.

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

Producción :

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

* or

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

No requiere un servidor Selenium para automatizar el navegador. Omite el espacio aislado de JavaScript utilizando eventos nativos a nivel del sistema operativo para manipular el navegador.

Además, contiene los enlaces .NET para la API Selenium WebDriver concisa y basada en objetos.

Selenium presenta un paquete de diferentes herramientas de software, cada una con un enfoque diferente para admitir la automatización del navegador. Ofrece herramientas altamente flexibles para ubicar y manipular elementos dentro de un navegador y admite la automatización para múltiples plataformas de navegador.

Utilice HttpClient para iniciar sesión en un sitio web en C#

Puede ayudarlo a acceder a la respuesta de inicio de sesión real, ya que el código de estado para la redirección es 3**; debe deshabilitar la redirección con HttpClient. Envía las credenciales para solicitar la URL utilizando el método de solicitud HTTP verb (o puede ser el método POST en la mayoría de los casos).

Siempre es fácil implementar un método de inicio de sesión basado en las cookies que el servidor espera recibir del usuario que ha iniciado sesión, y esta información se basa en los datos que contiene el encabezado set-cookie.

Puede usar los métodos GET y POST en HttpClient para iniciar sesión en un sitio web, ya que GET no incluye el cuerpo HTTP. Con un POST, los datos se mueven desde el QueryString al cuerpo HTTP.

Las credenciales de usuario o los datos que pasará se pasarán a través de parámetros, y el resto estará codificado de forma rígida. Lo que es más importante, la instancia del par clave-valor (KeyValuePair<string, string>) representa la secuencia especificada de datos de formulario que pueden ayudarlo a iniciar sesión en el sitio web mediante programación.

A veces, puede suceder que solo se requieran los datos especificados por el usuario, y es un paso esencial para que usted solicite el sitio web y analice HTML usando AngleSharp o cualquier método similar si el sitio web requiere que incluya campos ocultos desde la página de inicio de sesión.

En conclusión, la secuencia resultante con claves y valores (cadenas anulables) se pasa al constructor FormUrlEncodedContent (espera que las claves y los valores de la secuencia sean cadenas anulables).

// 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
        }
      }

      //....
    }
  }
}

Producción :

[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

La instancia del constructor FormUrlEncodedContent es el contenido principal de la solicitud POST en la llamada PostAsync, y después de realizar esta llamada, el siguiente paso es analizar los encabezados set-cookie de la respuesta HTTP. Siempre es una elección difícil encontrar un buen paquete NuGet en la biblioteca de clases de .NET, y es por eso que el análisis es la mejor manera mediante el uso de una expresión regular.

Verifique la cookie de respuesta para detectar un inicio de sesión fallido, verifique el código de estado de la respuesta del servidor o analice el contenido HTML devuelto por el servidor. Llamar a LoginAsync antes de descargar la página solicitada siempre es una excelente opción para recuperar o devolver las cookies de inicio de sesión para que las use para la solicitud al servidor.

Si no encuentra una sobrecarga del método GetStringAsync incorporado con un parámetro para cookies, cree un método de extensión usted mismo, ya que observará su creación en el siguiente código C#. Antes de utilizar el método SendAsync para enviar la solicitud (solicitud HTTP generada), debe combinar todas las cookies en un solo encabezado de cookie.

Es una opción si desea deshabilitar la función de redirección automática de HttpClient si el código de estado de respuesta de inicio de sesión requiere redirección. Se puede hacer con la instancia HttpClient ya que es posible hacer esto con IHttpClientFactory pasando la opción al registrar el HttpClient para inyección de dependencia.

Como no hay una funcionalidad integrada en HttpClient o .NET, en general, para iniciar sesión en un sitio web mediante programación, debe realizar manualmente todos los pasos, y es posible que cada vez que el proceso sea diferente. Debido a que los datos de autenticación o inicio de sesión se establecen en una cookie, configure el CookieContainer para realizar un inicio de sesión en un sitio web estándar de FormsAuthentication utilizando el HttpClient.

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

Artículo relacionado - Csharp Authentication