Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este tema se describe cómo enviar y recibir cookies HTTP en la API web.
Información general sobre las cookies HTTP
En esta sección se proporciona información general sobre cómo se implementan las cookies en el nivel HTTP. Para obtener más información, consulte RFC 6265.
Una cookie es un fragmento de datos que un servidor envía en la respuesta HTTP. El cliente (opcionalmente) almacena la cookie y la devuelve en las solicitudes posteriores. Esto permite que el cliente y el servidor compartan el estado. Para establecer una cookie, el servidor incluye un encabezado Set-Cookie en la respuesta. El formato de una cookie es un par nombre-valor, con atributos opcionales. Por ejemplo:
Set-Cookie: session-id=1234567
Este es un ejemplo con atributos:
Set-Cookie: session-id=1234567; max-age=86400; domain=example.com; path=/;
Para devolver una cookie al servidor, el cliente incluye un encabezado Cookie en solicitudes posteriores.
Cookie: session-id=1234567
Una respuesta HTTP puede incluir varios encabezados de Set-Cookie.
Set-Cookie: session-token=abcdef;
Set-Cookie: session-id=1234567;
El cliente devuelve varias cookies mediante un único encabezado cookie.
Cookie: session-id=1234567; session-token=abcdef;
El ámbito y la duración de una cookie se controlan mediante los atributos siguientes en el encabezado Set-Cookie:
- Dominio: indica al cliente qué dominio debe recibir la cookie. Por ejemplo, si el dominio es "example.com", el cliente devuelve la cookie a cada subdominio de example.com. Si no se especifica, el dominio es el servidor de origen.
- Ruta de acceso: restringe la cookie a la ruta de acceso especificada dentro del dominio. Si no se especifica, se utiliza la ruta del URI de la solicitud.
- Expira: establece una fecha de expiración para la cookie. El cliente elimina la cookie cuando expira.
- Max-Age: establece la antigüedad máxima de la cookie. El cliente elimina la cookie cuando alcanza la edad máxima.
Si se establecen Expires y Max-Age, Max-Age tiene prioridad. Si no se establece ninguno, el cliente elimina la cookie cuando finaliza la sesión actual. (El significado exacto de "sesión" viene determinado por el agente de usuario).
Sin embargo, tenga en cuenta que los clientes pueden omitir las cookies. Por ejemplo, un usuario podría deshabilitar las cookies por motivos de privacidad. Los clientes pueden eliminar cookies antes de que expiren o limitar el número de cookies almacenadas. Por motivos de privacidad, los clientes suelen rechazar cookies de "terceros", donde el dominio no coincide con el servidor de origen. En resumen, el servidor no debe confiar en recuperar las cookies que establece.
Cookies en Web API
Para agregar una cookie a una respuesta HTTP, cree una instancia de CookieHeaderValue que represente la cookie. A continuación, llame al método de extensión AddCookies , que se define en System.Net.Http. Clase HttpResponseHeadersExtensions para agregar la cookie.
Por ejemplo, el código siguiente agrega una cookie dentro de una acción del controlador:
public HttpResponseMessage Get()
{
var resp = new HttpResponseMessage();
var cookie = new CookieHeaderValue("session-id", "12345");
cookie.Expires = DateTimeOffset.Now.AddDays(1);
cookie.Domain = Request.RequestUri.Host;
cookie.Path = "/";
resp.Headers.AddCookies(new CookieHeaderValue[] { cookie });
return resp;
}
Observe que AddCookies toma una matriz de instancias de CookieHeaderValue .
Para extraer las cookies de una solicitud de cliente, llame al método GetCookies :
string sessionId = "";
CookieHeaderValue cookie = Request.Headers.GetCookies("session-id").FirstOrDefault();
if (cookie != null)
{
sessionId = cookie["session-id"].Value;
}
CookieHeaderValue contiene una colección de instancias de CookieState. Cada CookieState representa una cookie. Use el método indexador para obtener un cookieState por nombre, como se muestra.
Datos estructurados de cookies
Muchos exploradores limitan cuántas cookies almacenarán, tanto el número total como el número por dominio. Por lo tanto, puede ser útil colocar datos estructurados en una sola cookie, en lugar de establecer varias cookies.
Nota:
RFC 6265 no define la estructura de los datos de cookies.
Con la clase CookieHeaderValue , puede pasar una lista de pares nombre-valor para los datos de cookies. Estos pares nombre-valor se codifican como datos de formulario con codificación URL en el encabezado Set-Cookie:
var resp = new HttpResponseMessage();
var nv = new NameValueCollection();
nv["sid"] = "12345";
nv["token"] = "abcdef";
nv["theme"] = "dark blue";
var cookie = new CookieHeaderValue("session", nv);
resp.Headers.AddCookies(new CookieHeaderValue[] { cookie });
El código anterior genera el siguiente encabezado Set-Cookie:
Set-Cookie: session=sid=12345&token=abcdef&theme=dark+blue;
La clase CookieState proporciona un método de indexador para leer los subvalores de una cookie en el mensaje de solicitud:
string sessionId = "";
string sessionToken = "";
string theme = "";
CookieHeaderValue cookie = Request.Headers.GetCookies("session").FirstOrDefault();
if (cookie != null)
{
CookieState cookieState = cookie["session"];
sessionId = cookieState["sid"];
sessionToken = cookieState["token"];
theme = cookieState["theme"];
}
Ejemplo: Establecer y recuperar cookies en un controlador de mensajes
En los ejemplos anteriores se mostró cómo usar cookies desde un controlador de API web. Otra opción es usar controladores de mensajes. Los manejadores de mensajes se invocan antes en la canalización que los controladores. Un controlador de mensajes puede leer cookies de la solicitud antes de que la solicitud llegue al controlador o agregar cookies a la respuesta después de que el controlador genere la respuesta.
El código siguiente muestra un controlador de mensajes para crear identificadores de sesión. El identificador de sesión se almacena en una cookie. El controlador comprueba la solicitud de la cookie de sesión. Si la solicitud no incluye la cookie, el controlador genera un nuevo identificador de sesión. En cualquier caso, el controlador almacena el identificador de sesión en el contenedor de propiedades HttpRequestMessage.Properties . También agrega la cookie de sesión a la respuesta HTTP.
Esta implementación no valida que el servidor emitió realmente el identificador de sesión del cliente. ¡No lo use como forma de autenticación! El punto del ejemplo es mostrar la administración de cookies HTTP.
using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
public class SessionIdHandler : DelegatingHandler
{
public static string SessionIdToken = "session-id";
async protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
string sessionId;
// Try to get the session ID from the request; otherwise create a new ID.
var cookie = request.Headers.GetCookies(SessionIdToken).FirstOrDefault();
if (cookie == null)
{
sessionId = Guid.NewGuid().ToString();
}
else
{
sessionId = cookie[SessionIdToken].Value;
try
{
Guid guid = Guid.Parse(sessionId);
}
catch (FormatException)
{
// Bad session ID. Create a new one.
sessionId = Guid.NewGuid().ToString();
}
}
// Store the session ID in the request property bag.
request.Properties[SessionIdToken] = sessionId;
// Continue processing the HTTP request.
HttpResponseMessage response = await base.SendAsync(request, cancellationToken);
// Set the session ID as a cookie in the response message.
response.Headers.AddCookies(new CookieHeaderValue[] {
new CookieHeaderValue(SessionIdToken, sessionId)
});
return response;
}
}
Un controlador puede obtener el identificador de sesión del contenedor de propiedades HttpRequestMessage.Properties .
public HttpResponseMessage Get()
{
string sessionId = Request.Properties[SessionIdHandler.SessionIdToken] as string;
return new HttpResponseMessage()
{
Content = new StringContent("Your session ID = " + sessionId)
};
}