2009-05-30 17 views
62

soy relativamente nuevo en el uso de C#, y tienen una aplicación que lee partes del código fuente en un sitio web. Eso todo funciona; pero el problema es que la página en cuestión requiere que el usuario inicie sesión para acceder a este código fuente. Lo que mi programa necesita es una manera de registrar inicialmente al usuario en el sitio web; una vez hecho esto, podré acceder y leer el código fuente.de sesión en el sitio web, a través de C#

La página web que necesita ser conectado a decir: mmoinn.com/index.do?PageModule=UsersLogin

He buscado durante todo el día acerca de cómo hacer esto y trató de ejemplos, pero he tenido sin suerte.

Gracias de antemano

+0

Por lo tanto, se puede pensar en un montón de maneras de hacer esto ... ¿El El programa C# solicita el 'código' directamente desde el servidor a través de HTTP o ¿se conecta a la aplicación del navegador o qué? Se necesita un poco más de información. –

+0

El programa usa WebClient.DownloadString ("URL") –

Respuesta

95

Puede seguir utilizando WebClient para POST (en lugar de GET, que es el HTTP verb que está utilizando actualmente con DownloadString), pero creo que le resultará 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 se trata de utilizar la autenticación basada en cookies, que estoy bastante seguro de que es lo que devuelve una página de cabecera Set-cookie que incluye "PHPSESSID").


publicación en el formulario de acceso

mensajes de formulario son fáciles de simular, es sólo un caso de dar formato a los datos de envío de la siguiente manera:

field1=value1&field2=value2 

Usando WebRequest y el código Adapté de Scott Hanselman, aquí es cómo se había puesto los datos del formulario a su formulario de entrada:

string formUrl = "http://www.mmoinn.com/index.do?PageModule=UsersAction&Action=UsersLogin"; // NOTE: This is the URL the form POSTs to, not the URL of the form (you can find this in the "action" attribute of the HTML's form tag 
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"]; 

He aquí un ejemplo de lo que debería ver en la cabecera Set-Cookie para su formulario de entrada:

PHPSESSID=c4812cffcf2c45e0357a5a93c137642e; path=/; domain=.mmoinn.com,wowmine_referer=directenter; path=/; domain=.mmoinn.com,lang=en; path=/;domain=.mmoinn.com,adt_usertype=other,adt_host=- 

Obteniendo la página detrás de la forma de la conexión

Ahora puede realizar su GET solicite 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(); 
} 

EDIT:

Si necesita ver los resultados de la primera entrada, puede recuperar el código HTML se volvió con:

using (StreamReader sr = new StreamReader(resp.GetResponseStream())) 
{ 
    pageSource = sr.ReadToEnd(); 
} 

Coloque esta directamente debajo cookieHeader = resp.Headers["Set-cookie"]; y luego inspeccione la cadena que se encuentra en pageSource.

+0

Muchas gracias por la respuesta detallada; pero todavía hay una parte de la que no estoy seguro. ¿Se supone que debo cambiar algo con respecto a "Set -cookie", "Cookie" o el "PHPSESSID" que publicó? Intenté simplemente usar ese código en un programa al ingresar mi información, pero parece que no me está conectando (supongo que estoy arruinando algo con las cookies). –

+0

El código debería estar bien para usar textualmente. El servidor establece la cookie (en Set-cookie) y el cliente (ese eres tú) envía la cookie nuevamente como Cookie. Lo primero que debe comprobar es que el primer POST realmente inicia sesión, puede encontrar que el servidor esperaba otro campo en su formulario POST (aunque parezca extraño, a veces necesita un campo vacío con el nombre del botón). He actualizado la publicación para mostrar cómo ver los resultados de la POST. –

+0

No estoy seguro de lo que estaba haciendo mal la primera vez, ¡pero funciona ahora! Muchas gracias por la ayuda. –

30

Puede simplificar un poco las cosas creando una clase que se deriva de WebClient, anulando su método GetWebRequest y estableciendo un objeto CookieContainer en él. Si siempre configura la misma instancia de CookieContainer, la gestión de cookies se gestionará automáticamente.

Pero la única manera de llegar a HttpWebRequest antes de que se envíe es heredar de WebClient y anular ese método.

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

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

var client = new CookieAwareWebClient(); 
client.BaseAddress = @"https://www.site.com/any/base/url/"; 
var loginData = new NameValueCollection(); 
loginData.Add("login", "YourLogin"); 
loginData.Add("password", "YourPassword"); 
client.UploadValues("login.php", "POST", loginData); 

//Now you are logged in and can request pages  
string htmlSource = client.DownloadString("index.php"); 
+0

código muy bueno, pero no funciona bien para ajax páginas – Smith

+1

funciona bien! otras soluciones no funcionaron para mi sitio! gracias – pila

+0

Al depurar, la cookie (hecha pública) siempre está vacía. El sitio web está seguro de dar cookies en las páginas que estoy descargando. – C4u

2

A veces, puede ayudar a apagar AllowAutoRedirect y el establecimiento de ambas POST inicio de sesión y la página de solicitudes GET el mismo agente de usuario.

request.UserAgent = userAgent; 
request.AllowAutoRedirect = false; 
6

Matthew Brindley, su código funcionó muy bien para algún sitio web que necesitaba (con entrada), pero necesitaba cambiar a HttpWebRequest y HttpWebResponse lo contrario consigo un 404 Bad Request desde el servidor remoto. También me gustaría compartir mi solución utilizando su código, y es que lo intenté para iniciar sesión en un sitio web basado en moodle, pero no funcionó en su paso "OBTENER la página detrás del formulario de inicio de sesión" porque con éxito POSTing el inicio de sesión, el encabezado 'Set-Cookie' no devolvió nada, a pesar de que otros sitios web lo hacen.

Así que creo que es aquí donde tenemos que almacenar cookies para próximas solicitudes, así que agregué esto.


Para el "publicación en el formulario de acceso" bloque de código:

var cookies = new CookieContainer(); 
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(formUrl); 
req.CookieContainer = cookies; 


ya la "Obteniendo la página detrás de la forma de la conexión":

HttpWebRequest getRequest = (HttpWebRequest)WebRequest.Create(getUrl); 
getRequest.CookieContainer = new CookieContainer(); 
getRequest.CookieContainer.Add(resp.Cookies); 
getRequest.Headers.Add("Cookie", cookieHeader); 


Haciendo esto, me permite Conéctame y obtenga el código fuente de la "página detrás del inicio de sesión" (moodle basado en sitio web) Sé que este es un uso vago de las CookieContainer y HTTPCookies porque podemos preguntar primero si hay un conjunto previamente guardado de las cookies antes de enviar la solicitud al servidor . Esto funciona sin problema de todos modos, pero aquí es una buena información para leer sobre WebRequest y WebResponse con proyectos de ejemplo y tutorial:
Retrieving HTTP content in .NET
How to use HttpWebRequest and HttpWebResponse in .NET

Cuestiones relacionadas