HTMX 與 Django 的整合中,CSRF 令牌處理是必不可少的部分。特別是在像 POST 請求這樣的狀態變更操作中,必須適當利用 Django 的基本 CSRF 保護以維持安全性。本篇將詳細探討如何在 HTMX 與 Django 中處理 CSRF 令牌

Integration of CSRF token in Django and HTMX for secure web development

1. 什麼是 CSRF?

CSRF(跨站請求偽造)是一種攻擊技術,利用來自已獲認證的用戶的惡意請求發送至伺服器。Django 預設啟用 CSRF 防護功能,並驗證所有POST 請求的 CSRF 令牌。因此,在整合 HTMX 與 Django 時,必須遵守這一安全機制。

2. 如何在 HTMX 中處理 CSRF 令牌

在 HTMX 請求中處理 CSRF 令牌有兩種方法。只需選擇其中一種方式即可。

2.1 方法 1: 使用 HTML <meta> 標籤與 JavaScript 腳本

此方法適合當 HTMX 請求發生在 <form> 標籤之外的情況。例如,當 hx-post 屬性在 <button><div> 標籤上使用時。

設定方法
  1. 將 CSRF 令牌插入 HTML <meta> 標籤
    <meta name="csrf-token" content="{{ csrf_token }}">
  2. 編寫腳本自動將 CSRF 令牌添加到 HTMX 請求中
    <script>
        document.body.addEventListener('htmx:configRequest', function (event) {
            event.detail.headers['X-CSRFToken'] = document.querySelector('meta[name="csrf-token"]').content;
        });
    </script>

2.2 方法 2: 使用 HTML <form> 標籤與 {% csrf_token %}

此方法為 Django 預設使用的方式。如果 HTMX 的 hx-post<form> 標籤內發生,只需插入 {% csrf_token %} 即可。

設定方法
<form hx-post="/submit-form/" hx-target="#form-result">
    {% csrf_token %}
    <input type="text" name="name" placeholder="請輸入姓名">
    <button type="submit">提交</button>
</form>
<div id="form-result"></div>

3. CSRF 處理方式比較

特徵 <meta> 標籤 + JavaScript <form> 標籤 + {% csrf_token %}
使用情況 從 <form> 外部觸發 HTMX 請求 從 <form> 內部觸發 HTMX 請求
需編寫代碼 需編寫 <script> 僅需插入 {% csrf_token %}
適用範圍 可應用於所有 HTMX 請求 僅限 <form> 標籤內部請求

4. 預防 HTMX 與 CSRF 相關的錯誤

4.1 CSRF 相關錯誤的原因

當 Django 進行 POST 請求時如果 CSRF 令牌缺失,將會產生 403 Forbidden 錯誤。這是因為 CSRF 令牌未正確傳遞。

4.2 防止錯誤的檢查清單

  • 檢查 CSRF 令牌:確保 HTML <meta> 標籤或 <form> 標籤中添加了 CSRF 令牌。
  • 確認 HTMX 腳本運行:確認 CSRF 令牌已正確包含在 HTMX 請求中。
  • 檢查 Django 中介軟件:確認 CSRF 中介軟件(django.middleware.csrf.CsrfViewMiddleware)已啟用。

5. 插入 CSRF 令牌的額外提示

5.1 使用 hx-headers 插入 CSRF 令牌

透過使用 HTMX 的 hx-headers 屬性,可以輕鬆添加 CSRF 令牌,而無需編寫腳本。

<button 
    hx-post="/submit/" 
    hx-target="#result" 
    hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'>
    POST 請求
</button>
<div id="result">結果將顯示在這裡。</div>

此方法的優點

  • 無需編寫 <meta> 標籤和腳本。
  • 每個請求明確定義標頭,使代碼簡潔。
  • 可以靈活地為單個請求添加 CSRF 令牌。

使用時注意事項

  • 當 HTMX 請求較多時,需為每個請求編寫 hx-headers,可能導致代碼重複。
  • 如果需要全局處理,使用 <meta> 標籤和腳本會更有效率。

結束語

本篇中,我們詳細介紹了 Django 與 HTMX 整合時如何處理 CSRF 令牌。根據HTMX 請求是在 <form> 標籤內還是外部發生,選擇適當的方法進行應用。

在下一篇中,我們將探討HTMX 的進階功能(例如 hx-trigger、事件觸發、動態數據處理等),進一步擴展 HTMX 的應用。敬請期待!😊