### CSRF 防御方法

**1. 验证 HTTP Referer**

`Referer` 是 HTTP 请求头中的一个字段，它记录了请求的来源页面。通过检查 `Referer`，可以判断请求是否来自可信的域名

- **优点**：简单、易于实现
- **缺点**：
  - **不可靠**：`Referer` 字段可以被伪造或被某些浏览器、安全软件禁用
  - **隐私问题**：在某些情况下，浏览器可能不会发送 `Referer` 头，导致正常请求被阻止

**2. 添加 CSRF Token（推荐）**

这是防御 CSRF 最有效、最普遍的方法。CSRF Token 是一个随机生成的、只有服务器和用户端知道的令牌

- **工作原理**：
  1. 当用户访问一个页面时，服务器会生成一个唯一的、随机的 CSRF Token，并将其嵌入到表单中
  2. 当用户提交表单时，这个 Token 会随请求一起发送到服务器
  3. 服务器在处理请求前，会验证该 Token 是否有效。如果 Token 缺失或不匹配，请求就会被拒绝
- **优点**：
  - **安全性高**：攻击者无法获取用户的 Token，因此无法伪造有效的请求
  - **可防御跨站请求**：即使攻击者能诱导用户访问恶意网站，也无法获取到正确的 Token
- **实现方式**：
  - **Session Token**：将 Token 存储在用户的 Session 中
  - **双重提交Cookie**：将 Token 同时存放在 Cookie 和请求参数中

**3. 在 HTTP 头中使用自定义属性**

现代 Web 应用框架，如 Spring、Django 等，通常会内置 CSRF 防御机制。它们会在请求中添加一个自定义的 HTTP 头，并由服务器进行验证

- **工作原理**：当用户发送 AJAX 请求时，框架会自动在请求头中添加一个自定义属性，如 `X-CSRFToken`。服务器在接收请求后，会验证该 Token 是否正确
- **优点**：
  - **方便**：对于使用这些框架的开发者来说，实现起来非常简单
  - **不受 `Referer` 影响**：不依赖于浏览器的 `Referer` 头

**4. 验证码机制**

在一些关键操作（如修改密码、转账）中，要求用户输入验证码，可以有效防止 CSRF 攻击

- **优点**：
  - **安全性高**：验证码需要人工输入，无法被自动化
  - **简单直观**：用户容易理解
- **缺点**：
  - **用户体验差**：在每次操作时都要求输入验证码，会降低用户体验
  - **不适用于所有场景**：不适合频繁或批量操作

**5. Samesite Cookie 属性**

`SameSite` 是一个 HTTP Cookie 属性，它可以限制 Cookie 在跨站点请求中的发送行为

- **工作原理**：
  - **Strict**：最严格的模式，浏览器在跨站点请求时不会发送 Cookie，可以有效防御 CSRF
  - **Lax**：相对宽松的模式，在顶级导航 GET 请求（如点击链接）时会发送 Cookie，但在其他情况下不会
- **优点**：
  - **浏览器原生支持**：不需要额外开发
  - **简单有效**：可以作为 CSRF 防御的第一道防线
- **缺点**：
  - **兼容性问题**：在一些旧版浏览器中可能不受支持