Soubory cookie HTTP ve webovém rozhraní API technologie ASP.NET

Toto téma popisuje, jak odesílat a přijímat soubory cookie HTTP ve webovém rozhraní API.

Základní informace o souborech COOKIE PROTOKOLU HTTP

Tato část poskytuje stručný přehled o tom, jak se soubory cookie implementují na úrovni HTTP. Podrobnosti najdete v dokumentu RFC 6265.

Soubor cookie je část dat, která server odesílá v odpovědi HTTP. Klient (volitelně) soubor cookie uloží a vrátí ho při následných požadavcích. To umožňuje klientovi a serveru sdílet stav. Pokud chcete nastavit soubor cookie, server do odpovědi zahrne hlavičku Set-Cookie. Formát souboru cookie je pár název-hodnota s volitelnými atributy. Příklad:

Set-Cookie: session-id=1234567

Tady je příklad s atributy:

Set-Cookie: session-id=1234567; max-age=86400; domain=example.com; path=/;

Aby klient vrátil soubor cookie na server, zahrne hlavičku cookie do pozdějších požadavků.

Cookie: session-id=1234567

Diagram procesu vrácení souboru cookie na server, během kterého klient zahrne hlavičku cookie do pozdějších požadavků

Odpověď HTTP může obsahovat více hlaviček Set-Cookie.

Set-Cookie: session-token=abcdef;
Set-Cookie: session-id=1234567;

Klient vrátí více souborů cookie pomocí jedné hlavičky cookie.

Cookie: session-id=1234567; session-token=abcdef;

Rozsah a doba trvání souboru cookie jsou řízeny následujícími atributy v hlavičce Set-Cookie:

  • Doména: Řekne klientovi, která doména má soubor cookie přijmout. Pokud je například doména "example.com", klient vrátí soubor cookie do každé subdomény example.com. Pokud není zadáno, doména je počátečním serverem.
  • Cesta: Omezí soubor cookie na zadanou cestu v rámci domény. Pokud není zadaný, použije se cesta k identifikátoru URI požadavku.
  • Vyprší: Nastaví datum vypršení platnosti souboru cookie. Klient soubor cookie po vypršení jeho platnosti odstraní.
  • Max-Age: Nastaví maximální stáří souboru cookie. Jakmile klient dosáhne maximálního stáří, soubor cookie odstraní.

Pokud jsou nastaveny obě ExpiresMax-Age a, Max-Age má přednost. Pokud není nastavená žádná, klient po ukončení aktuální relace soubor cookie odstraní. (Přesný význam "relace" určuje uživatel-agent.)

Mějte ale na paměti, že klienti můžou soubory cookie ignorovat. Uživatel může například zakázat soubory cookie z důvodu ochrany osobních údajů. Klienti mohou soubory cookie odstranit před vypršením jejich platnosti nebo omezit počet uložených souborů cookie. Z důvodu ochrany osobních údajů klienti často odmítnou soubory cookie "třetích stran", kde doména neodpovídá zdrojovému serveru. Stručně řečeno, server by neměl spoléhat na získání souborů cookie, které nastaví.

Soubory cookie ve webovém rozhraní API

Chcete-li přidat soubor cookie do odpovědi HTTP, vytvořte cookieHeaderValue instance, která představuje soubor cookie. Pak zavolejte metodu rozšíření AddCookies , která je definována v System.Net.Http. HttpResponseHeadersExtensions třídy pro přidání souboru cookie.

Například následující kód přidá soubor cookie v rámci akce kontroleru:

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;
}

Všimněte si, že AddCookies přebírá pole CookieHeaderValue instance.

Pokud chcete extrahovat soubory cookie z požadavku klienta, zavolejte metodu GetCookies :

string sessionId = "";

CookieHeaderValue cookie = Request.Headers.GetCookies("session-id").FirstOrDefault();
if (cookie != null)
{
    sessionId = cookie["session-id"].Value;
}

CookieHeaderValue obsahuje kolekci CookieState instance. Každý cookieState představuje jeden soubor cookie. Pomocí metody indexeru získáte CookieState podle názvu, jak je znázorněno na obrázku.

Mnoho prohlížečů omezuje počet souborů cookie, které budou ukládat – celkový počet i počet na doménu. Proto může být užitečné vložit strukturovaná data do jednoho souboru cookie místo nastavení více souborů cookie.

Poznámka

RFC 6265 nedefinuje strukturu dat souborů cookie.

Pomocí CookieHeaderValue třídy můžete předat seznam párů název-hodnota pro data cookie. Tyto páry název-hodnota jsou v hlavičce Set-Cookie zakódovány jako data formuláře kódovaná adresou URL:

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 });

Předchozí kód vytvoří následující hlavičku Set-Cookie:

Set-Cookie: session=sid=12345&token=abcdef&theme=dark+blue;

Třída CookieState poskytuje metodu indexeru pro čtení dílčích hodnot z souboru cookie ve zprávě požadavku:

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"];
}

Příklad: Nastavení a načtení souborů cookie v obslužné rutině zprávy

Předchozí příklady ukázaly, jak používat soubory cookie z kontroleru webového rozhraní API. Další možností je použít obslužné rutiny zpráv. Obslužné rutiny zpráv jsou v kanálu vyvolány dříve než kontrolery. Obslužná rutina zprávy může číst soubory cookie z požadavku před tím, než požadavek dosáhne kontroleru, nebo přidat soubory cookie do odpovědi poté, co kontroler vygeneruje odpověď.

Diagram procesu nastavení a příjmu souborů cookie v obslužné rutině zprávy Ukazuje, jak se obslužné rutiny zpráv v kanálu volají dříve než kontrolery.

Následující kód ukazuje obslužnou rutinu zprávy pro vytváření ID relací. ID relace je uloženo v souboru cookie. Obslužná rutina zkontroluje požadavek na soubor cookie relace. Pokud požadavek neobsahuje soubor cookie, obslužná rutina vygeneruje nové ID relace. V obou případech obslužná rutina ukládá ID relace do kontejneru vlastností HttpRequestMessage.Properties . Přidá také soubor cookie relace do odpovědi HTTP.

Tato implementace neověřuje, že id relace z klienta bylo skutečně vydáno serverem. Nepoužívejte ho jako formu ověřování! Cílem příkladu je zobrazit správu souborů cookie 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;
    }
}

Kontroler může získat ID relace z kontejneru vlastností HttpRequestMessage.Properties .

public HttpResponseMessage Get()
{
    string sessionId = Request.Properties[SessionIdHandler.SessionIdToken] as string;

    return new HttpResponseMessage()
    {
        Content = new StringContent("Your session ID = " + sessionId)
    };
}