escribir - crear html desde c#
Iniciar sesiĆ³n en un sitio web usando C#mediante programaciĆ³n (2)
Por lo tanto, he estado buscando en la web tratando de obtener más información acerca de cómo iniciar sesión en sitios web programáticamente utilizando C #. No quiero usar un cliente web. Creo que quiero usar algo como HttpWebRequest y HttpWebResponse, pero no tengo idea de cómo funcionan estas clases.
Supongo que estoy buscando a alguien que me explique cómo funcionan y los pasos necesarios para iniciar sesión con éxito en, digamos, WordPress, una cuenta de correo electrónico o cualquier sitio que requiera que complete un formulario con un nombre de usuario y contraseña.
Aquí está uno de mis intentos:
// Declare variables
string url = textBoxGetSource.Text;
string username = textBoxUsername.Text;
string password = PasswordBoxPassword.Password;
// Values for site login fields - username and password html ID''s
string loginUsernameID = textBoxUsernameID.Text;
string loginPasswordID = textBoxPasswordID.Text;
string loginSubmitID = textBoxSubmitID.Text;
// Connection parameters
string method = "POST";
string contentType = @"application/x-www-form-urlencoded";
string loginString = loginUsernameID + "=" + username + "&" + loginPasswordID + "=" + password + "&" + loginSubmitID;
CookieContainer cookieJar = new CookieContainer();
HttpWebRequest request;
request = (HttpWebRequest)WebRequest.Create(url);
request.CookieContainer = cookieJar;
request.Method = method;
request.ContentType = contentType;
request.KeepAlive = true;
using (Stream requestStream = request.GetRequestStream())
using (StreamWriter writer = new StreamWriter(requestStream))
{
writer.Write(loginString, username, password);
}
using (var responseStream = request.GetResponse().GetResponseStream())
using (var reader = new StreamReader(responseStream))
{
var result = reader.ReadToEnd();
Console.WriteLine(result);
richTextBoxSource.AppendText(result);
}
MessageBox.Show("Successfully logged in.");
No sé si estoy en el camino correcto o no. Termino siendo devuelto a la pantalla de inicio de sesión de cualquier sitio que intento. He descargado Fiddler y pude obtener un poco de información sobre qué información se envía al servidor, pero me siento completamente perdido. Si alguien pudiera arrojar algo de luz aquí, lo agradecería mucho.
Iniciar sesión en sitios web programáticamente es difícil y está estrechamente relacionado con la forma en que el sitio implementa su procedimiento de inicio de sesión. La razón por la que su código no funciona es porque no está tratando con nada de esto en sus solicitudes / respuestas.
Tomemos fif.com por ejemplo. Cuando ingresas un nombre de usuario y contraseña, se envía la siguiente solicitud de publicación:
POST https://fif.com/login?task=user.login HTTP/1.1
Host: fif.com
Connection: keep-alive
Content-Length: 114
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: https://fif.com
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.103 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: https://fif.com/login?return=...==
Accept-Encoding: gzip,deflate
Accept-Language: en-US,en;q=0.8
Cookie: 34f8f7f621b2b411508c0fd39b2adbb2=gnsbq7hcm3c02aa4sb11h5c87f171mh3; __utma=175527093.69718440.1410315941.1410315941.1410315941.1; __utmb=175527093.12.10.1410315941; __utmc=175527093; __utmz=175527093.1410315941.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmv=175527093.|1=RegisteredUsers=Yes=1
username=...&password=...&return=aHR0cHM6Ly9maWYuY29tLw%3D%3D&9a9bd5b68a7a9e5c3b06ccd9b946ebf9=1
Observe las cookies (especialmente la primera, su token de sesión). Observe el críptico valor de retorno codificado en la url que se envía. Si el servidor nota que faltan, no le permitirá iniciar sesión.
HTTP/1.1 400 Bad Request
O peor, una respuesta 200 de una página de inicio de sesión con un mensaje de error enterrado en algún lugar dentro.
Pero imaginemos que fue posible recopilar todos esos valores mágicos y pasarlos en un objeto HttpWebRequest. El sitio no sabría la diferencia. Y podría responder con algo como esto.
HTTP/1.1 303 See other
Server: nginx
Date: Wed, 10 Sep 2014 02:29:09 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Location: https://fif.com/
Espero que estuvieras esperando eso. Pero si has llegado hasta aquí, ahora puedes disparar programáticamente las solicitudes al servidor con tu token de sesión ahora validado y recuperar el HTML esperado.
GET https://fif.com/ HTTP/1.1
Host: fif.com
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.103 Safari/537.36
Referer: https://fif.com/login?return=aHR0cHM6Ly9maWYuY29tLw==
Accept-Encoding: gzip,deflate
Accept-Language: en-US,en;q=0.8
Cookie: 34f8f7f621b2b411508c0fd39b2adbb2=gnsbq7hcm3c02aa4sb11h5c87f171mh3; __utma=175527093.69718440.1410315941.1410315941.1410315941.1; __utmb=175527093.12.10.1410315941; __utmc=175527093; __utmz=175527093.1410315941.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmv=175527093.|1=RegisteredUsers=Yes=1
Y esto es todo por fif.com: este malabarismo de cookies y tokens y redirecciones será completamente diferente para otro sitio. En mi experiencia (con ese sitio en particular), tienes tres opciones para atravesar el muro de inicio de sesión.
- Escribe un guión increíblemente complicado y frágil para bailar alrededor de los procedimientos del sitio
- Inicie sesión manualmente en el sitio con su navegador, tome los valores mágicos y conéctelos a sus objetos de solicitud o
- Cree una secuencia de comandos para automatizar el selenio para que lo haga por usted.
Selenium puede manejar todos los malabares, y al final puede sacar las cookies y despedir sus solicitudes normalmente. Aquí hay un ejemplo para fif:
//Run selenium
ChromeDriver cd = new ChromeDriver(@"chromedriver_win32");
cd.Url = @"https://fif.com/login";
cd.Navigate();
IWebElement e = cd.FindElementById("username");
e.SendKeys("...");
e = cd.FindElementById("password");
e.SendKeys("...");
e = cd.FindElementByXPath(@"//*[@id=""main""]/div/div/div[2]/table/tbody/tr/td[1]/div/form/fieldset/table/tbody/tr[6]/td/button");
e.Click();
//Get the cookies
foreach(OpenQA.Selenium.Cookie c in cd.Manage().Cookies.AllCookies)
{
string name = c.Name;
string value = c.Value;
cc.Add(new System.Net.Cookie(name,value,c.Path,c.Domain));
}
//Fire off the request
HttpWebRequest hwr = (HttpWebRequest) HttpWebRequest.Create("https://fif.com/components/com_fif/tools/capacity/values/");
hwr.CookieContainer = cc;
hwr.Method = "POST";
hwr.ContentType = "application/x-www-form-urlencoded";
StreamWriter swr = new StreamWriter(hwr.GetRequestStream());
swr.Write("feeds=35");
swr.Close();
WebResponse wr = hwr.GetResponse();
string s = new System.IO.StreamReader(wr.GetResponseStream()).ReadToEnd();
Pagar esta publicación Es otra forma de hacerlo y no necesita instalar ningún paquete, aunque podría ser más fácil con Selenium.
"Puedes continuar usando WebClient para POST (en lugar de GET, que es el verbo HTTP que estás usando actualmente con DownloadString), pero creo que te será más fácil trabajar con las clases (ligeramente) de menor nivel WebRequest y WebResponse .
Hay dos partes para esto: la primera es publicar el formulario de inicio de sesión, la segunda es recuperar el encabezado "Establecer cookies" y enviarlo al servidor como "Cookie" junto con su solicitud GET. El servidor usará esta cookie para identificarlo a partir de ahora (suponiendo que está usando autenticación basada en cookies, y estoy bastante seguro de que es así porque esa página devuelve un encabezado Set-cookie que incluye "PHPSESSID").
POSTING al formulario de inicio de sesión
Las publicaciones de formularios son fáciles de simular, solo se trata de formatear los datos de tus publicaciones de la siguiente manera:
field1=value1&field2=value2
Utilizando WebRequest y el código I adaptado de Scott Hanselman , aquí se explica cómo enviar datos de formulario a su formulario de inicio de sesión:
string formUrl = "http://www.mmoinn.com/index.do?PageModule=UsersAction&Action=UsersLogin";
NOTA: Esta es la URL a la que pertenece el formulario POST, no la URL del formulario (puede encontrarlo en el atributo "acción" de la etiqueta de formulario del HTML)
string formParams = string.Format("email_address={0}&password={1}", "your email", "your password"); string cookieHeader; WebRequest req = WebRequest.Create(formUrl); 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(); cookieHeader = resp.Headers["Set-cookie"];
Aquí hay un ejemplo de lo que debería ver en el encabezado Set-cookie para su formulario de inicio de sesión:
PHPSESSID=c4812cffcf2c45e0357a5a93c137642e; path=/; domain=.mmoinn.com,wowmine_referer=directenter; path=/;
domain = .mmoinn.com, lang = en; path = /; domain = .mmoinn.com, adt_usertype = other, adt_host = -
OBTENER LA PÁGINA DETRÁS DEL FORMULARIO
Ahora puede realizar su solicitud GET a una página para la que necesita iniciar sesión.
string pageSource; string getUrl = "the url of the page behind the 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(); }
EDITAR:
Si necesita ver los resultados del primer POST, puede recuperar el HTML que devolvió:
using (StreamReader sr = new StreamReader(resp.GetResponseStream())) { pageSource = sr.ReadToEnd(); }
Coloque esto directamente debajo de
cookieHeader = resp.Headers["Set-cookie"];
y luego inspeccione la cadena que se encuentra en pageSource ".