# Django 5.2.9 - dokumentacja

# Jak używać ochrony CSRF w Django

Aby skorzystać z ochrony CSRF w swoich widokach, wykonaj następujące kroki:

1. CSRF middleware jest domyślnie włączone w ustawieniu `MIDDLEWARE`. Jeśli nadpisujesz to ustawienie, pamiętaj, że `django.middleware.csrf.CsrfViewMiddleware'` powinno pojawić się przed jakimkolwiek view middleware, które zakłada, że ataki CSRF zostały opanowane.

   Jeśli go wyłączyłeś, co nie jest zalecane, możesz użyć `csrf_protect()` na poszczególnych widokach, które chcesz chronić (zobacz poniżej).

2. W dowolnym szablonie, który używa formularza POST, użyj tagu `csrf_token` wewnątrz elementu `<form>` jeśli formularz jest dla wewnętrznego adresu URL, np:

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

   Nie należy tego robić w przypadku formularzy POST, które kierują do zewnętrznych adresów URL, ponieważ spowodowałoby to wyciek tokena CSRF, prowadząc do luki.

3. W odpowiednich funkcjach widoku, upewnij się, że `RequestContext` jest używany do renderowania odpowiedzi, tak aby `{% csrf_token %}` działał poprawnie. Jeśli używasz funkcji `render()`, widoków generycznych, lub aplikacji contrib, jest już zawarta, ponieważ wszystkie one używają `RequestContext`.

## Używanie ochrony CSRF z AJAX-em

Podczas gdy powyższa metoda może być użyta dla żądań AJAX POST, ma ona pewne niedogodności: musisz pamiętać, aby przekazać token CSRF jako dane POST z każdym żądaniem POST. Z tego powodu istnieje alternatywna metoda: na każdym XMLHttpRequest, ustaw niestandardowy nagłówek `X-CSRFToken` (określony przez ustawienie `CSRF_HEADER_NAME`) na wartość tokena CSRF. Jest to często łatwiejsze, ponieważ wiele frameworków JavaScript zapewnia haki, które umożliwiają ustawienie nagłówków na każdym żądaniu.

Najpierw musisz uzyskać token CSRF. Jak to zrobić, zależy od tego, czy ustawienia `CSRF_USE_SESSIONS` i `CSRF_COOKIE_HTTPONLY` są włączone.

### Pozyskanie tokena jeśli `CSRF_USE_SESSIONS` i `CSRF_COOKIE_HTTPONLY` są `False`.

Zalecanym źródłem tokena jest ciasteczko `csrftoken`, które będzie ustawione, jeśli włączyłeś ochronę CSRF dla swoich widoków, jak opisano powyżej.

Plik cookie z tokenem CSRF jest domyślnie nazwany `csrftoken`, ale możesz kontrolować nazwę pliku cookie poprzez ustawienie `CSRF_COOKIE_NAME``

Token można nabyć w ten sposób:

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

Powyższy kod można by uprościć, używając biblioteki JavaScript Cookie` <https://github.com/js-cookie/js-cookie/>`_ do zastąpienia `getCookie`:

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

Informacja

CSRF token jest również obecny w DOM w zamaskowanej formie, ale tylko wtedy, gdy jest wyraźnie zawarty przy użyciu `csrf_token` w szablonie. Ciasteczko zawiera kanoniczny, niezamaskowany token. The `CsrfViewMiddleware` będzie akceptować każdy z nich. Jednakże, w celu ochrony przed atakami `BREACH`_attacks, zalecane jest użycie zamaskowanego tokena.

Ostrzeżenie

Jeśli twój widok nie renderuje szablonu zawierającego tag szablonu `csrf_token`, Django może nie ustawić ciasteczka CSRF token. Jest to powszechne w przypadkach, gdy formularze są dynamicznie dodawane do strony. Aby rozwiązać ten przypadek, Django dostarcza dekorator widoku, który wymusza ustawienie ciasteczka: `ensure_csrf_cookie()`.

### Pozyskanie tokena jeśli `CSRF_USE_SESSIONS` lub `CSRF_COOKIE_HTTPONLY` jest `True`.

Jeśli aktywujesz `CSRF_USE_SESSIONS` lub `CSRF_COOKIE_HTTPONLY`, musisz dołączyć token CSRF do swojego HTML i odczytać token z DOM za pomocą JavaScript:

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

### Ustawienie tokena w żądaniu AJAX

Na koniec będziesz musiał ustawić nagłówek na swoim żądaniu AJAX. Korzystanie z API fetch():

    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) {
        // ...
    });

## Używanie ochrony CSRF w szablonach Jinja2

Backend szablonów Django `Jinja2` dodaje `{ csrf_input }}` do kontekstu wszystkich szablonów, co jest odpowiednikiem `{% csrf_token %}` w języku szablonów Django. Na przykład:

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

## Użycie metody dekoratora

Zamiast dodawać `CsrfViewMiddleware` jako ogólną ochronę, możesz użyć dekoratora `csrf_protect`()`, który ma dokładnie taką samą funkcjonalność, na poszczególnych widokach, które potrzebują ochrony. Musi być używany zarówno na widokach, które wstawiają token CSRF do wyjścia, jak i na tych, które akceptują dane formularza POST. (Często są to te same funkcje widoku, ale nie zawsze).

Używanie dekoratora samego w sobie jest niezalecane, ponieważ jeśli zapomnisz go użyć, będziesz miał dziurę w zabezpieczeniach. Strategia „pasa i szelek” polegająca na używaniu obu jest w porządku i poniesie minimalny narzut.

## Obsługa odrzuconych wniosków

Domyślnie, odpowiedź «403 Forbidden» jest wysyłana do użytkownika, jeśli przychodzące żądanie nie przejdzie kontroli przeprowadzonej przez `CsrfViewMiddleware`. Powinno to być widoczne tylko wtedy, gdy istnieje prawdziwe Cross Site Request Forgery, lub gdy z powodu błędu programistycznego, token CSRF nie został dołączony do formularza POST.

Strona błędu nie jest jednak zbyt przyjazna, więc możesz chcieć zapewnić własny widok do obsługi tego warunku. Aby to zrobić, ustaw `CSRF_FAILURE_VIEW`.

Niepowodzenia CSRF są logowane jako ostrzeżenia do :ref:`django.security.csrf ` logger.

## Używanie ochrony CSRF z buforowaniem

Jeśli tag szablonu `csrf_token` jest użyty przez szablon (lub funkcja `get_token` jest wywołana w inny sposób), `CsrfViewMiddleware` doda ciasteczko i nagłówek `Vary: Cookie` do odpowiedzi. Oznacza to, że middleware będzie grał dobrze z cache middleware, jeśli jest używany zgodnie z instrukcją (`UpdateCacheMiddleware` idzie przed wszystkimi innymi middleware).

Jednakże, jeśli używasz dekoratorów cache na poszczególnych widokach, CSRF middleware nie będzie jeszcze w stanie ustawić nagłówka Vary lub CSRF cookie, a odpowiedź będzie buforowana bez żadnego z nich. W tym przypadku, na każdym widoku, który będzie wymagał wstawienia tokena CSRF powinieneś użyć najpierw dekoratora `django.views.decorators.csrf.csrf_protect()`:

    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): ...

Jeśli używasz widoków opartych na klasach, możesz odwołać się do Decorating widoków opartych na klasach.

## Testowanie i ochrona CSRF

The `CsrfViewMiddleware` will usually be a big hindrance to testing view functions, due to the need for the CSRF token which must be sent with every POST request. For this reason, Django’s HTTP client for tests has been modified to set a flag on requests which relaxes the middleware and the `csrf_protect` decorator so that they no longer rejects requests. In every other respect (e.g. sending cookies etc.), they behave the same.

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)

## Edge cases

Certain views can have unusual requirements that mean they don’t fit the normal pattern envisaged here. A number of utilities can be useful in these situations. The scenarios they might be needed in are described in the following section.

### Disabling CSRF protection for just a few views

Most views requires CSRF protection, but a few do not.

Solution: rather than disabling the middleware and applying `csrf_protect` to all the views that need it, enable the middleware and use `csrf_exempt()`.

### Setting the token when `CsrfViewMiddleware.process_view()` is not used

There are cases when `CsrfViewMiddleware.process_view` may not have run before your view is run - 404 and 500 handlers, for example - but you still need the CSRF token in a form.

Solution: use `requires_csrf_token()`

### Including the CSRF token in an unprotected view

There may be some views that are unprotected and have been exempted by `csrf_exempt`, but still need to include the CSRF token.

Solution: use `csrf_exempt()` followed by `requires_csrf_token()`. (i.e. `requires_csrf_token` should be the innermost decorator).

### Protecting a view for only one path

A view needs CSRF protection under one set of conditions only, and mustn’t have it for the rest of the time.

Solution: use `csrf_exempt()` for the whole view function, and `csrf_protect()` for the path within it that needs protection. Example:

    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()

### Protecting a page that uses AJAX without an HTML form

A page makes a POST request via AJAX, and the page does not have an HTML form with a `csrf_token` that would cause the required CSRF cookie to be sent.

Solution: use `ensure_csrf_cookie()` on the view that sends the page.

## CSRF protection in reusable applications

Because it is possible for the developer to turn off the `CsrfViewMiddleware`, all relevant views in contrib apps use the `csrf_protect` decorator to ensure the security of these applications against CSRF. It is recommended that the developers of other reusable apps that want the same guarantees also use the `csrf_protect` decorator on their views.