> ## Documentation Index
> Fetch the complete documentation index at: https://inertiajs-vi.tuantq.online/llms.txt
> Use this file to discover all available pages before exploring further.

# Bảo vệ CSRF

<Warning>Đây là tài liệu Inertia.js v1, phiên bản không còn được duy trì tích cực. Vui lòng tham khảo [tài liệu v3](/v3/getting-started/index).</Warning>

## Thực hiện request

Laravel tự động thêm CSRF token phù hợp khi thực hiện request qua Inertia hoặc Axios. Tuy nhiên, nếu dùng Laravel, hãy nhớ bỏ thẻ meta `csrf-token` khỏi dự án vì thẻ này sẽ ngăn CSRF token được làm mới đúng cách.

Nếu framework phía máy chủ có cơ chế bảo vệ cross-site request forgery (CSRF), bạn cần đảm bảo mỗi request Inertia đều chứa CSRF token cần thiết cho các request `POST`, `PUT`, `PATCH` và `DELETE`.

Tất nhiên, như đã đề cập, một số framework phía máy chủ như Laravel tự động xử lý việc đưa CSRF token vào request. **Vì vậy, khi dùng các framework này, bạn không cần cấu hình bổ sung.**

Tuy nhiên, nếu cần tự xử lý bảo vệ CSRF, một cách là gửi CSRF token dưới dạng prop trong mọi response. Sau đó bạn có thể sử dụng token này khi thực hiện request Inertia.

<CodeGroup>
  ```js Vue 2 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue2'

  router.post('/users', {
      _token: this.$page.props.csrf_token,
      name: 'John Doe',
      email: 'john.doe@example.com',
  })
  ```

  ```js Vue 3 icon="vuejs" theme={null}
  import { router, usePage } from '@inertiajs/vue3'

  const page = usePage()

  router.post('/users', {
      _token: page.props.csrf_token,
      name: 'John Doe',
      email: 'john.doe@example.com',
  })
  ```

  ```js React icon="react" theme={null}
  import { router, usePage } from '@inertiajs/react'

  const props = usePage().props

  router.post('/users', {
      _token: props.csrf_token,
      name: 'John Doe',
      email: 'john.doe@example.com',
  })
  ```

  ```js Svelte icon="s" theme={null}
  import { page, router } from '@inertiajs/svelte'

  router.post('/users', {
      _token: $page.props.csrf_token,
      name: 'John Doe',
      email: 'john.doe@example.com',
  })
  ```
</CodeGroup>

Bạn thậm chí có thể dùng chức năng [dữ liệu dùng chung](/v1/the-basics/shared-data) của Inertia để tự động gửi `csrf_token` trong mỗi response.

Tuy nhiên, cách tốt hơn là tận dụng chức năng CSRF có sẵn trong [axios](https://github.com/axios/axios). Axios là thư viện HTTP mà Inertia sử dụng bên dưới.

Axios tự động kiểm tra cookie `XSRF-TOKEN` có tồn tại hay không. Nếu có, nó sẽ gửi token trong header `X-XSRF-TOKEN` cho mọi request được tạo.

Cách dễ nhất để triển khai là dùng middleware phía máy chủ. Chỉ cần gửi cookie `XSRF-TOKEN` trong mỗi response, sau đó xác minh token bằng header `X-XSRF-TOKEN` được Axios gửi trong request.

## Xử lý token không khớp

Khi CSRF token không khớp, framework phía máy chủ thường ném exception dẫn đến response lỗi. Ví dụ, khi dùng Laravel, `TokenMismatchException` được ném và dẫn đến trang lỗi `419`. Vì đây không phải response Inertia hợp lệ nên lỗi sẽ được hiển thị trong modal.

<video controls>
  <source src="https://mintcdn.com/tqt97/ijnwM_i4Gr-teyg5/mp4/csrf-mismatch-modal.mp4?fit=max&auto=format&n=ijnwM_i4Gr-teyg5&q=85&s=205a14b8a1512babde75e9323c04b3b0" type="video/mp4" data-path="mp4/csrf-mismatch-modal.mp4" />
</video>

Rõ ràng đây không phải trải nghiệm tốt cho người dùng. Cách xử lý tốt hơn là redirect về trang trước kèm flash message cho biết trang đã hết hạn. Kết quả sẽ là một response Inertia hợp lệ, trong đó flash message có sẵn dưới dạng prop để bạn hiển thị cho người dùng. Tất nhiên, bạn cần chia sẻ [flash message](/shared-data#flash-messages) với Inertia để cách này hoạt động.

Khi dùng Laravel, bạn có thể chỉnh exception handler của ứng dụng để tự động redirect người dùng về trang trước và flash message vào session. Bạn có thể thực hiện việc này bằng phương thức exception `respond` trong file `bootstrap/app.php`.

```php theme={null}
use Symfony\Component\HttpFoundation\Response;

->withExceptions(function (Exceptions $exceptions) {
    $exceptions->respond(function (Response $response) {
        if ($response->getStatusCode() === 419) {
            return back()->with([
                'message' => 'The page expired, please try again.',
            ]);
        }

        return $response;
    });
});
```

Kết quả cuối cùng mang lại trải nghiệm tốt hơn nhiều. Thay vì nhìn thấy modal lỗi, người dùng sẽ nhận thông báo rằng trang đã "hết hạn" và được yêu cầu thử lại.

<video controls>
  <source src="https://mintcdn.com/tqt97/ijnwM_i4Gr-teyg5/mp4/csrf-mismatch-warning.mp4?fit=max&auto=format&n=ijnwM_i4Gr-teyg5&q=85&s=04d209a2d879395a8c92fef4ef786d3c" type="video/mp4" data-path="mp4/csrf-mismatch-warning.mp4" />
</video>

***

## Tài liệu chính thức

Bài dịch này được đối chiếu từ [tài liệu Inertia.js v1 chính thức](https://inertiajs.com/docs/v1/advanced/csrf-protection). Nếu có khác biệt do phiên bản hoặc cập nhật mới, hãy ưu tiên tài liệu chính thức làm nguồn tham chiếu.
