2010-12-16 19 views
16

Tengo una acción ASP.NET MVC que envía una solicitud GET a otro servidor a través de HttpWebRequest. Me gustaría incluir todas las cookies en la solicitud de la acción original en la nueva solicitud. Algunas de las System.Web.HttpCookies en la solicitud original tienen valores de dominio vacíos (es decir, ""), que aparentemente no causa ningún problema. Cuando creo un System.Net.Cookie usando el nombre, el valor, la ruta y el dominio de cada una de estas cookies y lo agrego al CookieContainer de la solicitud, aparece este error:HttpWebRequest cookie con dominio vacío

"System.ArgumentException: El parámetro ' {0}' no puede ser una cadena vacía nombre de parámetro:. cookie.Domain"

Aquí hay un código que lanzar el mismo error (cuando se añade la cookie):

var request = (HttpWebRequest)WebRequest.Create("http://www.whatever.com"); 
request.Method = "GET"; 
request.CookieContainer = new CookieContainer(); 
request.CookieContainer.Add (new Cookie ("MyCookieName", "MyCookieValue", "/", "")); 

EDITAR

tipo tipo de solucionado esto mediante el uso de "localhost" para el dominio, en lugar del valor de cadena vacío o nulo de la HttpCookie original. Entonces, ¿por qué un dominio vacío no funciona para CookieContainer? ¿HttpCookie usa un valor vacío para indicar localhost o necesito encontrar otro arreglo para este problema?

+1

¿Qué estás tratando de hacer exactamente? Establecer una cookie con el dominio "localhost" en el contenedor cuando está enviando la solicitud a un servidor diferente no funcionará: la cookie no se enviará. Si puede describir su escenario y lo que está tratando de lograr, tal vez se revelará una mejor solución. – feroze

+0

Parece que está creando una página de paso, probablemente para scripts de sitios cruzados. Voy a publicar una respuesta a continuación con información de fondo. Por ahora mira https://en.wikipedia.org/wiki/HTTP_cookie para ver cómo funciona. El dominio es muy importante. – BrainSlugs83

+0

@ Angelisho tiene una buena respuesta a continuación que simplemente funciona. Llegué a la misma conclusión en mis pruebas antes de encontrar su respuesta. Básicamente: request.Headers.Add (HttpRequestHeader.Cookie, "MyCookieName = MyCookieValue"); – Brain2000

Respuesta

-1

Está tratando de enviar las cookies a localhost, ¿no?

¿Por qué no haces algo como esto en el que dar su propia máquina un nombre real:

  1. Editar su archivo de hosts y añadir una línea "127.0.0.1 myname.com"
  2. prueba usando myname.com - que es en realidad su servidor local.

Su navegador o aplicación no notará la diferencia y enviará cookies a myname.com si es allí donde pertenece la cookie.

información detallada:

  1. el archivo hosts en las ventanas se encuentra en C: \ Windows \ System32 \ drivers \ etc \ hosts
+0

No puede tener un dominio vacío, porque ¿a qué dominio se enviaría la cookie? –

9

Aviso:

Como indicado anteriormente por @feroze, configurar el dominio de cookies en localhost no va a funcionar tan bien para ti. Supongo que está escribiendo un ayudante que le permite canalizar las solicitudes HTTP a dominios extranjeros. Tenga en cuenta que esto no es una buena práctica y en muchos casos no es necesario (es decir, jQuery has a lot of cool cross-domain support built-in, consulte también el nuevo CORS specification). Pero a veces puede que se quede estancado al hacer esto (es decir, el recurso externo solo es XML y está en un servidor que no es compatible con CORS).

Antecedentes sobre dominios de cookies y cómo funcionan:

Si aún no lo ha echar un vistazo a HTTP Cookie: Domain and Path on Wikipedia - prácticamente todo lo que necesita saber está ahí.

Al evaluar una cookie, el dominio y la ruta se tienen en cuenta por tanto el cliente (el solicitante "local") y el servidor web (el que responde "extranjera"). Cuando un cliente solicita un recurso, el cliente debe enviar cookies solo cuando esas cookies coincidan con el dominio (o un parent domain más genérico) y la ruta (o una ruta padre más genérica) del URI que se solicita.

Los navegadores web lo manejan correctamente. Si un navegador web tiene una cookie para el dominio "localhost" y usted está solicitando "google.com", por ejemplo, esas cookies para el dominio "localhost" no se enviarán en la solicitud a "google.com". - De hecho, la mayoría de los navegadores modernos no solo no los enviarán, sino que los ignorarán por completo en los encabezados de respuesta de Set-Cookie que reciben (estos se denominan cookies de terceros, lo que permite la aceptación de cookies de terceros en su el navegador web es una gran preocupación de privacidad/seguridad, ¡no lo hagas!).

Funciona también en la otra dirección, aunque es poco probable que un cliente incluya una cookie de terceros en una solicitud, si lo hace, se supone que el servidor web extranjero la ignorará (e incluso algunas cookies para corregir dominios/rutas, a fin de evitar el infame super-cookie problema. (es decir, el servidor web que aloja "example.com" debe ignorar las cookies que pertenecen a su dominio principal: ".com", porque ".com" es un "sufijo público")).

Lo que debe hacer [si es necesario]:

El curso de acción que recomiendo para usted, es cuando se lee en las cookies de su cliente (no soy un tipo MVC, pero en regulares ASP.NET esto sería en Request.Cookies), recorra (asegúrese de filtrar las cookies legítimas de su sitio, especialmente SessionId, etc.) o use Path correctamente para que nunca se envíen a esta página en primer lugar) , añádelos de a uno a la colección de cookies de la solicitud saliente, reescribiendo el dominio para que sea "www.whatever.com" (según su ejemplo, si está haciendo esto de forma dinámica, cargue la URL en un nuevo Uri() objetar y usar la propiedad .Host), y luego establecer la ruta a "/". - Esto generará el encabezado "Cookie" para la solicitud de salida al servidor web extranjero.

Cuando la solicitud regrese a su servidor, debe verificar su respuesta entrante para nuevas cookies; esas cookies pueden volver a empaquetarse y enviarse de vuelta a su cliente en el mismo tipo de ciclo que ilustré en el anterior párrafo, excepto que querrá reescribir Host para que sea Request.Url.Host - y querrá establecer la ruta de regreso a "/" a menos que la ruta a su página de tránsito sea estática (supongo que no es ya que está usando MVC), entonces debería establecerlo en Request.Url.AbsolutePath, por ejemplo.

Happy Coding!

EDIT: Además, tendrá que fijar la etiqueta X-Forwarded-For de la solicitud de salida, por lo que el sitio web que está llamando no piensa en su servidor web es un solo cliente que ha sido spam a la mierda de ellos.

2

Algunos antecedentes

Esto se debe a que es CookieContainer del lado del cliente contenedor diseñado para ser reutilizado a través de múltiples HttpWebRequest. La reutilización proporciona el comportamiento de cookies esperado que las cookies establecidas por el host remoto se envían de vuelta con cada HttpWebRequests posterior dirigida al mismo host.

Como resultado de la reutilización, un CookieContainer en realidad podría contener cookies de varias solicitudes y/o hosts.

Por lo tanto, para determinar cuál de las cookies del contenedor debe enviarse con un HttpWebRequest particular a algún host (dominio), CookieContainer examina el dominio y la propiedad Path.

Es por eso que una Cookie en un CookieContainer necesita tener un Dominio válido.

Por el contrario, en el lado del servidor cookies se entregan a través de un tipo diferente, CookieCollection el que una simple lista de las cookies con ninguna lógica adicional.


En concreto, en su caso, al copiar las cookies de la CookieCollection a la CookieContainer que necesita para establecer la propiedad de dominio de cada cookie en el dominio de su van a reenviar la petición a, de modo que HttpWebRequest conocerán a incluir las cookies al enviar la solicitud.

1

No estoy seguro, resuelve tu problema. Pero para agregar cookies sin la propiedad "Dominio" debe agregar a los encabezados las cookies usando HttpRequestHeader.Cookie de la siguiente manera.

request.Headers.Add(HttpRequestHeader.Cookie, "Your cookies..."); 

Hope it helps!

+0

Encontré que esta era la única forma de hacer que una cookie solo funcionara al hacer una solicitud web, sin tener que intentar adivinar la ruta o el dominio. Parece que encontraste lo mismo. – Brain2000

Cuestiones relacionadas