# Dokumentasi Django 4.2.9.dev20231204082947

# Bagaimana menggunakan perlindungan CSRF Django

Untuk mengambil keuntungan dari perlindungan CSRF dalam tampilan anda, ikuti langkah-langkah ini:

1. Middleware CSRD diaktifkan secara awalan dalam pengaturan `MIDDLEWARE`. Jika anda menimpa pengaturan itu, ingat bahwa `'django.middleware.csrf.CsrfViewMiddleware'` harys datang sebelum tampilan middleware apapun yang menganggap bahwa serangan CSRF telah ditangani.

   Jika anda meniadakan itu, yang tidak dianjurkan, anda dapat menggunakan `csrf_protect()` pada tampilan tertentu anda ingin lindungi (lihat dibawah).

2. Dalam cetakan manapun yang menggunakan formulir POST, gunakan etiket `csrf_token` didalam unsur `<form>` jika formulir adalah untuk internalURL, misalnya:

       <form method="post">{% csrf_token %}

   Ini jangan diselesaikan untuk formulir POST yang sasaran external URL, sejak itu akan menyebabkan token CSRF bocor, membawa pada kerentanan.

3. Dalam fungsi tampilan sesuai, pastikan bahwa `RequestContext` digunakan untuk membangun tanggapan sehingga `{% csrf_token %}` akan bekerja dengan benar. Jika anda sedang menggunakan fungsi `render()`, tampilan umum, atau aplikasi bantuan, anda sudah dilindungi sejak ini semua menggunakan `RequestContext`.

## Menggunakan perlindungan CSRF dengan AJAX

Selagi metode diatas dapat digunakan untuk permintaan POST AJAX, itu memiliki beberapa ketidaknyamanan: anda harus ingat melewatkan token CSRF dalam sebuah data POST dengan setiap permintaan POST. Untuk alasan ini, ada metode lain: pada setiap XMLHttpRequest, setel sebuah penyesuaian kepala `X-CSRFToken` (seperti ditentukan oleh pengaturan `CSRF_HEADER_NAME`) pada nilai dari token CSRF. Ini sering lebih mudah karena banyak kerangka kerja JavaScript menyediakan kaitan yang mengizinkan kepala untuk disetel pada setiap permintaan.

Pertama, anda harus mendapatkan token CSRF. Bagaimana melakukan itu bergantung pada apakah atau tidak pengaturan `CSRF_USE_SESSIONS` dan `CSRF_COOKIE_HTTPONLY` diadakan.

### Memperoleh token jika `CSRF_USE_SESSIONS` atau `CSRF_COOKIE_HTTPONLY` adalah `False`

Sumber dianjurkan untuk token adalah kue `csrftoken`, yang akan disetel jika anda telah mengadakan perlindungan CSRF untuk tampilan anda seperti diuraikan diatas.

Kue token CSRD dinamakan `csrftoken` secara awalan, tetapi anda dapat mengendalikan nama kue melalui pengaturan `CSRF_COOKIE_NAME`.

Anda bisa mendapatkan token seperti ini:

    function getCookie(name) {
        let cookieValue = null;
        if (document.cookie && document.cookie !== '') {
            const cookies = document.cookie.split(';');
            for (let i = 0; i < cookies.length; i++) {
                const cookie = cookies[i].trim();
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) === (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
    const csrftoken = getCookie('csrftoken');

Kode diatas dapat disederhanakan menggunakan JavaScript Cookie library untuk mengganti `getCookie`:

    const csrftoken = Cookies.get('csrftoken');

Catatan

Token CSRF juga hadir dalam DOM dalam bentuk topeng, tetapi hanya jika secara eksplisit disertakan menggunakan `csrf_token` dalam cetakan. Cookie mengandung resmi, token tidak bertopeng. `CsrfViewMiddleware` akan menerima baik. Bagaimanapun, agar terlindungi terhadap BREACH attacks, dianjurkan untuk menggunakan token bertopeng.

Peringatan

Jika tampilan anda tidak membangun sebuah cetakan mengandung etiket cetakan `csrf_token`, Django mugkin tidak menyetel kue token CSRF. Ini adalah umum dalam kasus-kasus dimana formulir secara dinamis ditambahkan ke halaman. Untuk mengalamatkan ke kasus ini, Django menyediakan penghias tampilan yang memaksa mengatur kue: `ensure_csrf_cookie()`.

### Memperoleh token jika `CSRF_USE_SESSIONS` atau `CSRF_COOKIE_HTTPONLY` adalah `True`

Jika anda mengkatifkan `CSRF_USE_SESSIONS` atau `CSRF_COOKIE_HTTPONLY`, anda harus menyertakan token CSRF dalam HTML anda dan baca token dari DOM dengan JavaScript:

    {% csrf_token %}
    <script>
    const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
    </script>

### Mengatur token pada permintaan AJAX

Akhirnya, anda akan butuh menyetel kepala pada permintaan AJAX anda. Menggunakan fetch() API:

    const request = new Request(
        /* URL */,
        {
            method: 'POST',
            headers: {'X-CSRFToken': csrftoken},
            mode: 'same-origin' // Do not send CSRF token to another domain.
        }
    );
    fetch(request).then(function(response) {
        // ...
    });

## Menggunakan perlindungan CSRF dalam cetakan Jinja2

Backend cetakan `Jinja2` Django menambahkan `{{ csrf_input }}` ke konteks dari semua cetakan yang setara pada `{% csrf_token %}` dalam bahasa cetakan Django. Sebagai contoh:

    <form method="post">{{ csrf_input }}

## Menggunakan metode penghias

Daripada menambahkan `CsrfViewMiddleware` sebagai pelindung selimut, anda dapat menggunakan penghias `csrf_protect()`, yang mempunyai kegunaan yang sama, pada tampilan tertentu yang butuh perlindungan. Itu harus digunakan both pada tampilan yang memasukkan token CSRF dalam keluaran, danpada mereka itu menerima data formulir POST. (Ini seringkali merupakan fungsi tampilan yang sama, tetapi tidak selalu).

Gunakan dari penghias oleh itu sendiri adalah not recommended, sejak jika anda melupakan itu, anda akan mempunyai sebuah lubang keamanan. Strategi 'belt and braces' dari menggunakan keduanya adalah baik, dan akan mendatangkan beban minimal.

## Menangani permintaan tertolak

Secara awalan, tanggapan '403 Forbidden' dikirim ke pengguna jika sebuah permintaan datang gagal memeriksa dilakukan oleh `CsrfViewMiddleware`. Ini seharusnya hanya terlihat ketika ada Cross Site Request Forgery asli, atau ketika, karena kesalahan pemrograman, token CSRF tidak disertakan dalam formulir POST.

Halaman kesalahan, bagaimanapun, sangat tidak ramah, sehingga anda ingin menyediakan tampilan anda sendiri untuk menangani kondisi ini. Untuk melakukan ini, setel pengaturan `CSRF_FAILURE_VIEW`.

Kegagalan CSRF adalah tercatat sebagai peringatan pada pencatat django.security.csrf 1.

## Menggunakan perlindungan CSRF dengan caching

Jika etiket cetakan `csrf_token` digunakan oleh cetakan (atau fungsi `get_token` dipanggil cara lain), `CsrfViewMiddleware` akan menambah sebuah kue dan sebuah kepala `Vary: Cookie` ke tanggapan. Ini berarti bahwa middleware akan bermain baik dengan middleware cache jika itu digunakan sesuai panduan (`UpdateCacheMiddleware` berjalan sebelum semua middleware lain).

Bagaimanapun, jika anda menggunakan penghias cache pada tampilan masing-masing, middleware CSRF belum bisa menyetel kepala Vary atau kue CSRF, dan tanggapan akan di simpan sementara tanpa salah satu. Dalam kasus ini, pada tampilan apapun yang akan membutuhkan token CSRF untuk dimasukkan anda harus menggunakan penghias `django.views.decorators.csrf.csrf_protect()` dahulu:

    from django.views.decorators.cache import cache_page
    from django.views.decorators.csrf import csrf_protect

    @cache_page(60 * 15)
    @csrf_protect
    def my_view(request):
        ...

Jika anda sedang menggunakan tampilan berdasarkan-kelas, anda dapat mengacu ke Decorating class-based views1.

## Pengujian dan perlindungan CSRF

`CsrfViewMiddleware` biasanya akan menjadi penghalang besar untuk menguji fungsi tampilan, dikarenakan kebutuhan token CSRF yang harus dikirim setiap permintaan POST. Untuk alasan ini, Klien HTTP Django untuk percobaan telah dirubah untuk menyetel bendera pada permintaan middleware yang santai dan penghias `csrf_protect` sehingga mereka tidak lagi menolak permintaan. Dalam segala hal lainnya (misalnya mengirim cookies dll.), mereka berperilaku sama.

If, for some reason, you want the test client to perform CSRF checks, you can create an instance of the test client that enforces CSRF checks:

    >>> from django.test import Client
    >>> csrf_client = Client(enforce_csrf_checks=True)

## Kasus tepi

Tampilan-tampilan tertentu dapat memiliki persyaratan tidak biasa yang berarti mereka tidak cocok pola biasa dipertimbangkan disini. Sejumlah kegunaan dapat berguna dalam keadaan seperti ini. Skenario mereka mungkin dibutuhkan digambarkan dalam bagian berikut.

### Meniadakan perlindungan CSRF untuk hanya sedikit tampilan

Kebanyakan tampilan membutuhkan perlindungan CSRF, tetapi sedikit tidak.

Pemecahan: daripada meniadakan middleware dan memberlakukan `csrf_protect` ke semua tampilan yang membutuhkan itu, adakan middleware dan gunakan `csrf_exempt()`.

### Pengaturan token ketika `CsrfViewMiddleware.process_view()` tidak digunakan

Ada kasus-kasus ketika `CsrfViewMiddleware.process_view` mungkin tidak berjalan sebelum tampilan anda berjalan - penangan 404 dan 500, sebagai contoh - tetapi anda masih butuh token CSRF dalam sebuah formulir.

Pemecahan: gunakan `requires_csrf_token()`

### Memasukkan token CSRF dalam tampilan tidak terlindungi

Mungkin ada beberapa tampilan yang tidak terlindungi dan telah dibebaskan oleh `csrf_exempt`, tetapi masih butuh disertakan token CSRF.

Pemecahan: gunakan `csrf_exempt()` diikuti oleh `requires_csrf_token()`. (yaitu `requires_csrf_token` harus berupa penghias paling dalam).

### Melindungi tampilan hanya untuk satu jalur

Sebuah tampilan butuh perlindungan CSRF dibawah hanya satu kumpulan dari situasi, dan tidak boleh memilikinya untuk sisa waktu.

Pemecahan: gunakan `csrf_exempt()` untuk seluruh fungsi tampilan, dan `csrf_protect()` untuk jalur dalam itu yang butuh perlindungan. Contoh:

    from django.views.decorators.csrf import csrf_exempt, csrf_protect

    @csrf_exempt
    def my_view(request):
        @csrf_protect
        def protected_path(request):
            do_something()

        if some_condition():
            return protected_path(request)
        else:
            do_something_else()

### Melindungi halaman yang menggunakan AJAX tanpa formulir HTML

Sebuah halaman membuat permintaan POST melalui AJAX, dan halaman tidak mempunyai formulir HTML dengan `csrf_token` yang akan menyebabkan kue CSRF diwajibkan dikirim.

Pemecahan: gunakan `ensure_csrf_cookie()` di tampilan yang mengirim halaman.

## Perlindungan CSRF dalam aplikasi digunakan kembali

Karena itu memungkinkan untuk pengembang mematikan `CsrfViewMiddleware`, semua tampilan terkait dalam kontribusi aplikasi menggunakan penghias `csrf_protect` untuk memastikan keamanan aplikasi ini terhadap CSRF. Itu dianjurkan bahwa pengembang dari aplikasi yang digunakan kembali yang ingin jaminan sama juga menggunakan penghias `csrf_protect` pada tampilan mereka.