Bagikan melalui


Middleware Penembolokan Respons di ASP.NET Core

Oleh John Luo dan Rick Anderson

Artikel ini menjelaskan cara mengonfigurasi Middleware Penembolokan Respons di aplikasi ASP.NET Core. Middleware menentukan kapan respons dapat di-cache, menyimpan respons, dan melayani respons dari cache. Untuk pengenalan penembolokan HTTP dan [ResponseCache] atribut , lihat Penembolokan Respons.

Middleware penembolokan respons:

  • Mengaktifkan respons server penembolokan berdasarkan header cache HTTP. Menerapkan semantik penembolokan HTTP standar. Cache berdasarkan header cache HTTP seperti proksi.
  • Biasanya tidak bermanfaat untuk aplikasi UI seperti Razor Pages karena browser umumnya mengatur header permintaan yang mencegah penembolokan. Penembolokan output, yang tersedia di ASP.NET Core 7.0 dan yang lebih baru, menguntungkan aplikasi UI. Dengan penembolokan output, konfigurasi memutuskan apa yang harus di-cache secara independen dari header HTTP.
  • Mungkin bermanfaat untuk permintaan GET publik atau HEAD API dari klien tempat Ketentuan penembolokan terpenuhi.

Untuk menguji penembolokan respons, gunakan Fiddler, atau alat lain yang dapat secara eksplisit mengatur header permintaan. Mengatur header secara eksplisit lebih disukai untuk menguji penembolokan. Untuk informasi selengkapnya, lihat Pemecahan masalah.

Konfigurasi

Di Program.cs, tambahkan layanan AddResponseCaching Middleware Penembolokan Respons ke koleksi layanan dan konfigurasikan aplikasi untuk menggunakan middleware dengan UseResponseCaching metode ekstensi. UseResponseCaching menambahkan middleware ke alur pemrosesan permintaan:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddResponseCaching();

var app = builder.Build();

app.UseHttpsRedirection();

// UseCors must be called before UseResponseCaching
//app.UseCors();

app.UseResponseCaching();

Peringatan

UseCors harus dipanggil sebelumnya UseResponseCaching saat menggunakan middleware CORS.

Aplikasi sampel menambahkan header untuk mengontrol penembolokan pada permintaan berikutnya:

  • Cache-Control: Cache respons yang dapat di-cache hingga 10 detik.
  • Bervariasi: Mengonfigurasi middleware untuk melayani respons yang di-cache hanya jika header Accept-Encoding permintaan berikutnya cocok dengan permintaan asli.
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddResponseCaching();

var app = builder.Build();

app.UseHttpsRedirection();

// UseCors must be called before UseResponseCaching
//app.UseCors();

app.UseResponseCaching();

app.Use(async (context, next) =>
{
    context.Response.GetTypedHeaders().CacheControl =
        new Microsoft.Net.Http.Headers.CacheControlHeaderValue()
        {
            Public = true,
            MaxAge = TimeSpan.FromSeconds(10)
        };
    context.Response.Headers[Microsoft.Net.Http.Headers.HeaderNames.Vary] =
        new string[] { "Accept-Encoding" };

    await next();
});

app.MapGet("/", () => DateTime.Now.Millisecond);

app.Run();

Header sebelumnya tidak ditulis ke respons dan ditimpa saat pengontrol, tindakan, atau Razor Halaman:

Penembolokan Respons Middleware hanya menyimpan respons server yang menghasilkan kode status 200 (OK). Respons lain, termasuk halaman kesalahan, diabaikan oleh middleware.

Peringatan

Respons yang berisi konten untuk klien terautentikasi harus ditandai sebagai tidak dapat di-cache untuk mencegah middleware menyimpan dan melayani respons tersebut. Lihat Kondisi untuk penembolokan untuk detail tentang bagaimana middleware menentukan apakah respons dapat di-cache.

Kode sebelumnya biasanya tidak mengembalikan nilai cache ke browser. Gunakan Fiddler atau alat lain yang dapat secara eksplisit mengatur header permintaan dan lebih disukai untuk menguji penembolokan. Untuk informasi selengkapnya, lihat Pemecahan Masalah di artikel ini.

Opsi

Opsi penembolokan respons diperlihatkan dalam tabel berikut.

Opsi Deskripsi
MaximumBodySize Ukuran terbesar yang dapat di-cache untuk isi respons dalam byte. Nilai defaultnya adalah 64 * 1024 * 1024 (64 MB).
SizeLimit Batas ukuran untuk middleware cache respons dalam byte. Nilai defaultnya adalah 100 * 1024 * 1024 (100 MB).
UseCaseSensitivePaths Menentukan apakah respons di-cache pada jalur peka huruf besar/kecil. Nilai defaultnya adalah false.

Contoh berikut mengonfigurasi middleware untuk:

  • Respons cache dengan ukuran tubuh lebih kecil dari atau sama dengan 1.024 byte.
  • Simpan respons berdasarkan jalur peka huruf besar/kecil. Misalnya, /page1 dan /Page1 disimpan secara terpisah.
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddResponseCaching(options =>
{
    options.MaximumBodySize = 1024;
    options.UseCaseSensitivePaths = true;
});

var app = builder.Build();

app.UseHttpsRedirection();

// UseCors must be called before UseResponseCaching
//app.UseCors();

app.UseResponseCaching();

app.Use(async (context, next) =>
{
    context.Response.GetTypedHeaders().CacheControl =
        new Microsoft.Net.Http.Headers.CacheControlHeaderValue()
        {
            Public = true,
            MaxAge = TimeSpan.FromSeconds(10)
        };
    context.Response.Headers[Microsoft.Net.Http.Headers.HeaderNames.Vary] =
        new string[] { "Accept-Encoding" };

    await next(context);
});

app.MapGet("/", () => DateTime.Now.Millisecond);

app.Run();

VaryByQueryKeys

Saat menggunakan MVC, pengontrol API web, atau Razor model halaman Halaman, [ResponseCache] atribut menentukan parameter yang diperlukan untuk mengatur header yang sesuai untuk penembolokan respons. Satu-satunya [ResponseCache] parameter atribut yang benar-benar memerlukan middleware adalah VaryByQueryKeys, yang tidak sesuai dengan header HTTP aktual. Untuk informasi selengkapnya, lihat Penembolokan respons di ASP.NET Core.

Saat tidak menggunakan [ResponseCache] atribut , penembolokan respons dapat bervariasi dengan VaryByQueryKeys. ResponseCachingFeature Gunakan langsung dari HttpContext.Features:

var responseCachingFeature = context.HttpContext.Features.Get<IResponseCachingFeature>();

if (responseCachingFeature != null)
{
    responseCachingFeature.VaryByQueryKeys = new[] { "MyKey" };
}

Menggunakan nilai tunggal yang sama dengan * dalam VaryByQueryKeys berbagai cache oleh semua parameter kueri permintaan.

Header HTTP yang digunakan oleh Middleware Penembolokan Respons

Tabel berikut ini menyediakan informasi tentang header HTTP yang memengaruhi penembolokan respons.

Header Detail
Authorization Respons tidak di-cache jika header ada.
Cache-Control Middleware hanya mempertimbangkan respons penembolokan yang ditandai dengan arahan public cache. Mengontrol penembolokan dengan parameter berikut:
  • usia maks
  • maks-basi†
  • min-fresh
  • must-revalidate
  • no-cache
  • no-store
  • hanya-jika-di-cache
  • privat
  • publik
  • s-maxage
  • proxy-revalidate‡
†Jika tidak ada batas yang ditentukan untuk max-stale, middleware tidak mengambil tindakan.
proxy-revalidate‡ memiliki efek yang sama dengan must-revalidate.

Untuk informasi selengkapnya, lihat RFC 9111: Petunjuk Permintaan.
Pragma Header Pragma: no-cache dalam permintaan menghasilkan efek yang sama dengan Cache-Control: no-cache. Header ini ditimpa oleh arahan yang relevan di Cache-Control header, jika ada. Dipertimbangkan untuk kompatibilitas mundur dengan HTTP/1.0.
Set-Cookie Respons tidak di-cache jika header ada. Setiap middleware dalam alur pemrosesan permintaan yang menetapkan satu atau beberapa cookie mencegah Middleware Penembolokan Respons dari penembolokan respons (misalnya, cookiepenyedia TempData berbasis).
Vary Header Vary digunakan untuk memvariasikan respons yang di-cache oleh header lain. Misalnya, respons cache dengan mengodekan dengan menyertakan Vary: Accept-Encoding header, yang menyimpan respons untuk permintaan dengan header Accept-Encoding: gzip dan Accept-Encoding: text/plain secara terpisah. Respons dengan nilai * header tidak pernah disimpan.
Expires Respons yang dianggap basi oleh header ini tidak disimpan atau diambil kecuali ditimpa oleh header lain Cache-Control .
If-None-Match Respons penuh disajikan dari cache jika nilainya tidak * dan ETag respons tidak cocok dengan nilai apa pun yang disediakan. Jika tidak, respons 304 (Tidak Dimodifikasi) dilayani.
If-Modified-Since If-None-Match Jika header tidak ada, respons penuh disajikan dari cache jika tanggal respons yang di-cache lebih baru dari nilai yang disediakan. Jika tidak, respons 304 - Tidak Diubah dilayani.
Date Saat melayani dari cache, Date header diatur oleh middleware jika tidak disediakan pada respons asli.
Content-Length Saat melayani dari cache, Content-Length header diatur oleh middleware jika tidak disediakan pada respons asli.
Age Header Age yang dikirim dalam respons asli diabaikan. Middleware menghitung nilai baru saat melayani respons cache.

Penembolokan menghormati permintaan arahan Cache-Control

Middleware menghormati aturan RFC 9111: Penembolokan HTTP (Bagian 5.2. Cache-Control). Aturan memerlukan cache untuk menghormati header yang valid Cache-Control yang dikirim oleh klien. Di bawah spesifikasi, klien dapat membuat permintaan dengan no-cache nilai header dan memaksa server untuk menghasilkan respons baru untuk setiap permintaan. Saat ini, tidak ada kontrol pengembang atas perilaku penembolokan ini saat menggunakan middleware karena middleware mematuhi spesifikasi penembolokan resmi.

Untuk kontrol lebih lanjut atas perilaku penembolokan, jelajahi fitur penembolokan ASP.NET Core lainnya. Lihat topik berikut:

Pemecahan Masalah

Middleware Penembolokan Respons menggunakan IMemoryCache, yang memiliki kapasitas terbatas. Ketika kapasitas terlampaui, cache memori dipadatkan.

Jika perilaku penembolokan tidak seperti yang diharapkan, konfirmasikan bahwa respons dapat di-cache dan mampu dilayani dari cache. Periksa header masuk permintaan dan header keluar respons. Aktifkan pengelogan untuk membantu penelusuran kesalahan.

Saat menguji dan memecahkan masalah perilaku penembolokan, browser biasanya mengatur header permintaan yang mencegah penembolokan. Misalnya, browser dapat mengatur header ke Cache-Control no-cache atau max-age=0 saat me-refresh halaman. Fiddler dan alat lain dapat secara eksplisit mengatur header permintaan dan lebih disukai untuk menguji penembolokan.

Kondisi untuk penembolokan

  • Permintaan harus menghasilkan respons server dengan kode status 200 (OK).
  • Metode permintaan harus GET atau HEAD.
  • Middleware Penembolokan Respons harus ditempatkan sebelum middleware yang memerlukan penembolokan. Untuk informasi lebih lanjut, lihat Middleware ASP.NET Core.
  • Header Authorization tidak boleh ada.
  • Cache-Control parameter header harus valid, dan respons harus ditandai public dan tidak ditandai private.
  • Header Pragma: no-cache tidak boleh ada jika Cache-Control header tidak ada, karena Cache-Control header mengambil alih Pragma header saat ada.
  • Header Set-Cookie tidak boleh ada.
  • Vary parameter header harus valid dan tidak sama dengan *.
  • Nilai Content-Length header (jika diatur) harus cocok dengan ukuran isi respons.
  • IHttpSendFileFeature Tidak digunakan.
  • Respons tidak boleh kedaluarsa seperti yang ditentukan oleh Expires header dan arahan max-age cache dan s-maxage .
  • Buffering respons harus berhasil. Ukuran respons harus lebih kecil dari yang dikonfigurasi atau default SizeLimit. Ukuran isi respons harus lebih kecil dari yang dikonfigurasi atau default MaximumBodySize.
  • Respons harus dapat di-cache sesuai dengan RFC 9111: Penembolokan HTTP. Misalnya, arahan no-store tidak boleh ada di bidang header permintaan atau respons. Lihat RFC 9111: Penembolokan HTTP (Bagian 3: Menyimpan Respons di Cache untuk detailnya.

Catatan

Sistem Antiforgery untuk menghasilkan token aman untuk mencegah serangan Pemalsuan Permintaan Lintas Situs (CSRF) mengatur Cache-Control header dan Pragma ke no-cache sehingga respons tidak di-cache. Untuk informasi tentang cara menonaktifkan token antiforgery untuk elemen formulir HTML, lihat Mencegah serangan Pemalsuan Permintaan Lintas Situs (XSRF/CSRF) di ASP.NET Core.

Sumber Daya Tambahan:

Artikel ini menjelaskan cara mengonfigurasi Middleware Penembolokan Respons di aplikasi ASP.NET Core. Middleware menentukan kapan respons dapat di-cache, menyimpan respons, dan melayani respons dari cache. Untuk pengenalan penembolokan HTTP dan [ResponseCache] atribut , lihat Penembolokan Respons.

Melihat atau mengunduh kode sampel (cara mengunduh)

Konfigurasi

Middleware Penembolokan Respons tersedia secara implisit untuk aplikasi ASP.NET Core melalui kerangka kerja bersama.

Di Startup.ConfigureServices, tambahkan Middleware Penembolokan Respons ke koleksi layanan:

public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCaching();
    services.AddRazorPages();
}

Konfigurasikan aplikasi untuk menggunakan middleware dengan UseResponseCaching metode ekstensi, yang menambahkan middleware ke alur pemrosesan permintaan di Startup.Configure:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
    }

    app.UseStaticFiles();
    app.UseRouting();
    // UseCors must be called before UseResponseCaching
    // app.UseCors("myAllowSpecificOrigins");

    app.UseResponseCaching();

    app.Use(async (context, next) =>
    {
        context.Response.GetTypedHeaders().CacheControl = 
            new Microsoft.Net.Http.Headers.CacheControlHeaderValue()
            {
                Public = true,
                MaxAge = TimeSpan.FromSeconds(10)
            };
        context.Response.Headers[Microsoft.Net.Http.Headers.HeaderNames.Vary] = 
            new string[] { "Accept-Encoding" };

        await next();
    });

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Peringatan

UseCors harus dipanggil sebelumnya UseResponseCaching saat menggunakan middleware CORS.

Aplikasi sampel menambahkan header untuk mengontrol penembolokan pada permintaan berikutnya:

  • Cache-Control: Cache respons yang dapat di-cache hingga 10 detik.
  • Bervariasi: Mengonfigurasi middleware untuk melayani respons yang di-cache hanya jika header Accept-Encoding permintaan berikutnya cocok dengan permintaan asli.
// using Microsoft.AspNetCore.Http;

app.Use(async (context, next) =>
{
    context.Response.GetTypedHeaders().CacheControl = 
        new Microsoft.Net.Http.Headers.CacheControlHeaderValue()
        {
            Public = true,
            MaxAge = TimeSpan.FromSeconds(10)
        };
    context.Response.Headers[Microsoft.Net.Http.Headers.HeaderNames.Vary] = 
        new string[] { "Accept-Encoding" };

    await next();
});

Header sebelumnya tidak ditulis ke respons dan ditimpa saat pengontrol, tindakan, atau Razor Halaman:

Penembolokan Respons Middleware hanya menyimpan respons server yang menghasilkan kode status 200 (OK). Respons lain, termasuk halaman kesalahan, diabaikan oleh middleware.

Peringatan

Respons yang berisi konten untuk klien terautentikasi harus ditandai sebagai tidak dapat di-cache untuk mencegah middleware menyimpan dan melayani respons tersebut. Lihat Kondisi untuk penembolokan untuk detail tentang bagaimana middleware menentukan apakah respons dapat di-cache.

Opsi

Opsi penembolokan respons diperlihatkan dalam tabel berikut.

Opsi Deskripsi
MaximumBodySize Ukuran terbesar yang dapat di-cache untuk isi respons dalam byte. Nilai defaultnya adalah 64 * 1024 * 1024 (64 MB).
SizeLimit Batas ukuran untuk middleware cache respons dalam byte. Nilai defaultnya adalah 100 * 1024 * 1024 (100 MB).
UseCaseSensitivePaths Menentukan apakah respons di-cache pada jalur peka huruf besar/kecil. Nilai defaultnya adalah false.

Contoh berikut mengonfigurasi middleware untuk:

  • Respons cache dengan ukuran tubuh lebih kecil dari atau sama dengan 1.024 byte.
  • Simpan respons berdasarkan jalur peka huruf besar/kecil. Misalnya, /page1 dan /Page1 disimpan secara terpisah.
services.AddResponseCaching(options =>
{
    options.MaximumBodySize = 1024;
    options.UseCaseSensitivePaths = true;
});

VaryByQueryKeys

Saat menggunakan pengontrol API MVC / web atau Razor model halaman Pages, [ResponseCache] atribut menentukan parameter yang diperlukan untuk mengatur header yang sesuai untuk penembolokan respons. Satu-satunya [ResponseCache] parameter atribut yang benar-benar memerlukan middleware adalah VaryByQueryKeys, yang tidak sesuai dengan header HTTP aktual. Untuk informasi selengkapnya, lihat Penembolokan respons di ASP.NET Core.

Saat tidak menggunakan [ResponseCache] atribut , penembolokan respons dapat bervariasi dengan VaryByQueryKeys. ResponseCachingFeature Gunakan langsung dari HttpContext.Features:

var responseCachingFeature = context.HttpContext.Features.Get<IResponseCachingFeature>();

if (responseCachingFeature != null)
{
    responseCachingFeature.VaryByQueryKeys = new[] { "MyKey" };
}

Menggunakan nilai tunggal yang sama dengan * dalam VaryByQueryKeys berbagai cache oleh semua parameter kueri permintaan.

Header HTTP yang digunakan oleh Middleware Penembolokan Respons

Tabel berikut ini menyediakan informasi tentang header HTTP yang memengaruhi penembolokan respons.

Header Detail
Authorization Respons tidak di-cache jika header ada.
Cache-Control Middleware hanya mempertimbangkan respons penembolokan yang ditandai dengan arahan public cache. Mengontrol penembolokan dengan parameter berikut:
  • usia maks
  • maks-basi†
  • min-fresh
  • must-revalidate
  • no-cache
  • no-store
  • hanya-jika-di-cache
  • privat
  • publik
  • s-maxage
  • proxy-revalidate‡
†Jika tidak ada batas yang ditentukan untuk max-stale, middleware tidak mengambil tindakan.
proxy-revalidate‡ memiliki efek yang sama dengan must-revalidate.

Untuk informasi selengkapnya, lihat RFC 9111: Petunjuk Permintaan.
Pragma Header Pragma: no-cache dalam permintaan menghasilkan efek yang sama dengan Cache-Control: no-cache. Header ini ditimpa oleh arahan yang relevan di Cache-Control header, jika ada. Dipertimbangkan untuk kompatibilitas mundur dengan HTTP/1.0.
Set-Cookie Respons tidak di-cache jika header ada. Setiap middleware dalam alur pemrosesan permintaan yang menetapkan satu atau beberapa cookie mencegah Middleware Penembolokan Respons dari penembolokan respons (misalnya, cookiepenyedia TempData berbasis).
Vary Header Vary digunakan untuk memvariasikan respons yang di-cache oleh header lain. Misalnya, respons cache dengan mengodekan dengan menyertakan Vary: Accept-Encoding header, yang menyimpan respons untuk permintaan dengan header Accept-Encoding: gzip dan Accept-Encoding: text/plain secara terpisah. Respons dengan nilai * header tidak pernah disimpan.
Expires Respons yang dianggap basi oleh header ini tidak disimpan atau diambil kecuali ditimpa oleh header lain Cache-Control .
If-None-Match Respons penuh disajikan dari cache jika nilainya tidak * dan ETag respons tidak cocok dengan nilai apa pun yang disediakan. Jika tidak, respons 304 (Tidak Dimodifikasi) dilayani.
If-Modified-Since If-None-Match Jika header tidak ada, respons penuh disajikan dari cache jika tanggal respons yang di-cache lebih baru dari nilai yang disediakan. Jika tidak, respons 304 - Tidak Diubah dilayani.
Date Saat melayani dari cache, Date header diatur oleh middleware jika tidak disediakan pada respons asli.
Content-Length Saat melayani dari cache, Content-Length header diatur oleh middleware jika tidak disediakan pada respons asli.
Age Header Age yang dikirim dalam respons asli diabaikan. Middleware menghitung nilai baru saat melayani respons cache.

Penembolokan menghormati permintaan arahan Cache-Control

Middleware menghormati aturan RFC 9111: Penembolokan HTTP (Bagian 5.2. Cache-Control). Aturan memerlukan cache untuk menghormati header yang valid Cache-Control yang dikirim oleh klien. Di bawah spesifikasi, klien dapat membuat permintaan dengan no-cache nilai header dan memaksa server untuk menghasilkan respons baru untuk setiap permintaan. Saat ini, tidak ada kontrol pengembang atas perilaku penembolokan ini saat menggunakan middleware karena middleware mematuhi spesifikasi penembolokan resmi.

Untuk kontrol lebih lanjut atas perilaku penembolokan, jelajahi fitur penembolokan ASP.NET Core lainnya. Lihat topik berikut:

Pemecahan Masalah

Jika perilaku penembolokan tidak seperti yang diharapkan, konfirmasikan bahwa respons dapat di-cache dan mampu dilayani dari cache. Periksa header masuk permintaan dan header keluar respons. Aktifkan pengelogan untuk membantu penelusuran kesalahan.

Saat menguji dan memecahkan masalah perilaku penembolokan, browser dapat mengatur header permintaan yang memengaruhi penembolokan dengan cara yang tidak diinginkan. Misalnya, browser dapat mengatur header ke Cache-Control no-cache atau max-age=0 saat me-refresh halaman. Alat berikut dapat secara eksplisit mengatur header permintaan dan lebih disukai untuk menguji penembolokan:

Kondisi untuk penembolokan

  • Permintaan harus menghasilkan respons server dengan kode status 200 (OK).
  • Metode permintaan harus GET atau HEAD.
  • Di Startup.Configure, Middleware Penembolokan Respons harus ditempatkan sebelum middleware yang memerlukan penembolokan. Untuk informasi lebih lanjut, lihat Middleware ASP.NET Core.
  • Header Authorization tidak boleh ada.
  • Cache-Control parameter header harus valid, dan respons harus ditandai public dan tidak ditandai private.
  • Header Pragma: no-cache tidak boleh ada jika Cache-Control header tidak ada, karena Cache-Control header mengambil alih Pragma header saat ada.
  • Header Set-Cookie tidak boleh ada.
  • Vary parameter header harus valid dan tidak sama dengan *.
  • Nilai Content-Length header (jika diatur) harus cocok dengan ukuran isi respons.
  • IHttpSendFileFeature Tidak digunakan.
  • Respons tidak boleh kedaluarsa seperti yang ditentukan oleh Expires header dan arahan max-age cache dan s-maxage .
  • Buffering respons harus berhasil. Ukuran respons harus lebih kecil dari yang dikonfigurasi atau default SizeLimit. Ukuran isi respons harus lebih kecil dari yang dikonfigurasi atau default MaximumBodySize.
  • Respons harus dapat di-cache sesuai dengan RFC 9111: Penembolokan HTTP. Misalnya, arahan no-store tidak boleh ada di bidang header permintaan atau respons. Lihat RFC 9111: Penembolokan HTTP (Bagian 3: Menyimpan Respons di Cache untuk detailnya.

Catatan

Sistem Antiforgery untuk menghasilkan token aman untuk mencegah serangan Pemalsuan Permintaan Lintas Situs (CSRF) mengatur Cache-Control header dan Pragma ke no-cache sehingga respons tidak di-cache. Untuk informasi tentang cara menonaktifkan token antiforgery untuk elemen formulir HTML, lihat Mencegah serangan Pemalsuan Permintaan Lintas Situs (XSRF/CSRF) di ASP.NET Core.

Sumber Daya Tambahan: