Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Thema wird beschrieben, wie HTTP-Cookies in der Web-API gesendet und empfangen werden.
Hintergrund zu HTTP-Cookies
In diesem Abschnitt finden Sie eine kurze Übersicht darüber, wie Cookies auf HTTP-Ebene implementiert werden. Ausführliche Informationen finden Sie in RFC 6265.
Ein Cookie ist ein Datenteil, den ein Server in der HTTP-Antwort sendet. Der Client speichert das Cookie optional und gibt es bei nachfolgenden Anfragen zurück. Auf diese Weise können der Client und der Server den Zustand teilen. Um ein Cookie festzulegen, enthält der Server einen Set-Cookie Header in der Antwort. Das Format eines Cookies ist ein Name-Wert-Paar mit optionalen Attributen. Beispiel:
Set-Cookie: session-id=1234567
Hier ist ein Beispiel mit Attributen:
Set-Cookie: session-id=1234567; max-age=86400; domain=example.com; path=/;
Um ein Cookie an den Server zu senden, sendet der Client einen Cookie-Header bei späteren Anfragen.
Cookie: session-id=1234567
Eine HTTP-Antwort kann mehrere Set-Cookie Header enthalten.
Set-Cookie: session-token=abcdef;
Set-Cookie: session-id=1234567;
Der Client gibt mehrere Cookies mithilfe eines einzelnen Cookie-Headers zurück.
Cookie: session-id=1234567; session-token=abcdef;
Der Umfang und die Dauer eines Cookies werden durch die folgenden Attribute im Set-Cookie Header gesteuert:
- Domäne: Teilt dem Client mit, welche Domäne das Cookie empfangen soll. Wenn die Domäne beispielsweise "example.com" ist, gibt der Client das Cookie an jede Unterdomäne von example.com zurück. Wenn nicht angegeben, ist die Domäne der Ursprungsserver.
- Pfad: Beschränkt das Cookie auf den angegebenen Pfad innerhalb der Domäne. Wenn nicht angegeben, wird der Pfad des Anforderungs-URI verwendet.
- Läuft ab: Legt ein Ablaufdatum für das Cookie fest. Der Kunde löscht das Cookie, wenn es abläuft.
- Max-Age: Legt das maximale Alter für das Cookie fest. Der Kunde löscht das Cookie, wenn es das maximale Alter erreicht.
Wenn beide Expires und Max-Age festgelegt sind, hat Max-Age Vorrang. Wenn keines festgelegt ist, löscht der Client das Cookie, wenn die aktuelle Sitzung endet. (Die genaue Bedeutung von "Session" wird vom Benutzer-Agent bestimmt.)
Beachten Sie jedoch, dass Kunden Cookies ignorieren können. Ein Benutzer kann z. B. Cookies aus Datenschutzgründen deaktivieren. Kunden können Cookies löschen, bevor sie ablaufen, oder die Anzahl der gespeicherten Cookies einschränken. Aus Datenschutzgründen lehnen Clients häufig "Drittanbieter"-Cookies ab, bei denen die Domäne nicht mit dem Ursprungsserver übereinstimmt. Kurz gesagt, der Server sollte sich nicht darauf verlassen, die von ihr gesetzten Cookies zurückzuholen.
Cookies in der Web-API
Um einer HTTP-Antwort ein Cookie hinzuzufügen, erstellen Sie eine CookieHeaderValue-Instanz , die das Cookie darstellt. Rufen Sie dann die AddCookies-Erweiterungsmethode auf, die in der System.Net.Http definiert ist. HttpResponseHeadersExtensions-Klasse , um das Cookie hinzuzufügen.
Der folgende Code fügt z. B. ein Cookie innerhalb einer Controlleraktion hinzu:
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;
}
Beachten Sie, dass AddCookies ein Array von CookieHeaderValue-Instanzen verwendet.
Rufen Sie die GetCookies-Methode auf, um die Cookies aus einer Clientanforderung zu extrahieren:
string sessionId = "";
CookieHeaderValue cookie = Request.Headers.GetCookies("session-id").FirstOrDefault();
if (cookie != null)
{
sessionId = cookie["session-id"].Value;
}
Ein CookieHeaderValue enthält eine Sammlung von CookieState-Instanzen . Jeder CookieState stellt ein Cookie dar. Verwenden Sie die Indexermethode, um einen CookieState anhand des Namens abzurufen, wie dargestellt.
Strukturierte Cookie-Daten
Viele Browser beschränken die Anzahl der Cookies, die sie speichern werden – sowohl die Gesamtanzahl als auch die Anzahl pro Domäne. Daher kann es sinnvoll sein, strukturierte Daten in ein einzelnes Cookie zu setzen, anstatt mehrere Cookies festzulegen.
Hinweis
RFC 6265 definiert nicht die Struktur von Cookiedaten.
Mithilfe der CookieHeaderValue-Klasse können Sie eine Liste von Namen-Wert-Paaren für die Cookiedaten übergeben. Diese Namen-Wert-Paare werden als URL-codierte Formulardaten im Set-Cookie-Header codiert:
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 });
Der vorherige Code erzeugt den folgenden Set-Cookie Header:
Set-Cookie: session=sid=12345&token=abcdef&theme=dark+blue;
Die CookieState-Klasse stellt eine Indexermethode zum Lesen der Unterwerte aus einem Cookie in der Anforderungsnachricht bereit:
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"];
}
Beispiel: Festlegen und Abrufen von Cookies in einem Nachrichtenhandler
In den vorherigen Beispielen wurde gezeigt, wie Cookies aus einem Web-API-Controller verwendet werden. Eine weitere Option besteht darin, Nachrichtenhandler zu verwenden. Nachrichtenhandler werden in der Pipeline früher als Controller aufgerufen. Ein Nachrichtenhandler kann Cookies aus der Anforderung lesen, bevor die Anforderung den Controller erreicht, oder Cookies zur Antwort hinzufügen, nachdem der Controller die Antwort generiert hat.
Der folgende Code zeigt einen Meldungshandler zum Erstellen von Sitzungs-IDs. Die Sitzungs-ID wird in einem Cookie gespeichert. Der Handler überprüft die Anforderung für das Sitzungscookie. Wenn die Anforderung das Cookie nicht enthält, generiert der Handler eine neue Sitzungs-ID. In beiden Fällen speichert der Handler die Sitzungs-ID im Eigenschaftenbehälter "HttpRequestMessage.Properties ". Außerdem wird das Sitzungscookie zur HTTP-Antwort hinzugefügt.
Diese Implementierung überprüft nicht, ob die Sitzungs-ID vom Client tatsächlich vom Server ausgestellt wurde. Verwenden Sie sie nicht als Authentifizierungsform! Der Punkt des Beispiels besteht darin, die HTTP-Cookieverwaltung anzuzeigen.
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;
}
}
Ein Controller kann die Sitzungs-ID aus dem Eigenschaftenbehälter "HttpRequestMessage.Properties " abrufen.
public HttpResponseMessage Get()
{
string sessionId = Request.Properties[SessionIdHandler.SessionIdToken] as string;
return new HttpResponseMessage()
{
Content = new StringContent("Your session ID = " + sessionId)
};
}