# @dr\.pogodin/csurf 中文文档

规范地址：https://npmcn.com/package/%40dr.pogodin/csurf/

版本：1\.18\.2
npm 元数据更新时间：2026-10-15T09:58:29.804Z
中文译文更新时间：2026-11-12T18:41:27.594Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40dr.pogodin/csurf
原文对照：https://npmcn.com/package/%40dr.pogodin/csurf/?lang=original
项目主页：https://dr.pogodin.studio/docs/csurf
源码仓库：https://github.com/birdofpreyru/csurf

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：59.9 kB，11 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=22
- 运行依赖：3 个
- 首次发布：2022-11-04T21:43:04.843Z
- 最新版本发布：2026-10-15T09:58:29.526Z
- 近 30 天下载量：76717（2026-10-13 至 2026-11-11，npm 官方下载统计）
- 已发布版本数：25（近 12 个月 7 个）

## 中文简介

ExpressJS 的 CSRF 代号中间软件

## 安装

```sh
npm install @dr.pogodin/csurf
```

也可以使用：`pnpm add @dr.pogodin/csurf`、`yarn add @dr.pogodin/csurf`、`bun add @dr.pogodin/csurf`

## README

# 简历

[![Latest NPM Release](https://img.shields.io/npm/v/@dr.pogodin/csurf.svg)](https://www.npmjs.com/package/@dr.pogodin/csurf) [![NPM Downloads](https://img.shields.io/npm/dm/@dr.pogodin/csurf.svg)](https://www.npmjs.com/package/@dr.pogodin/csurf) [![CircleCI](https://dl.circleci.com/status-badge/img/gh/birdofpreyru/csurf/tree/master.svg?style=shield)](https://app.circleci.com/pipelines/github/birdofpreyru/csurf) [![GitHub Repo stars](https://img.shields.io/github/stars/birdofpreyru/csurf?style=social)](https://github.com/birdofpreyru/csurf) [![Dr. Pogodin Studio](https://raw.githubusercontent.com/birdofpreyru/csurf/master/.README/logo-dr-pogodin-studio.svg)](https://dr.pogodin.studio/docs/csurf)

节点.js [中国证监会](https://en.wikipedia.org/wiki/Cross-site_request_forgery) 保护中间软件 [运通JS](https://expressjs.com/)。 。 。 .

[![Sponsor](https://raw.githubusercontent.com/birdofpreyru/csurf/master/.README/sponsor.svg)](https://github.com/sponsors/birdofpreyru)

### [贡献者](https://github.com/birdofpreyru/csurf/graphs/contributors)

[![](https://avatars.githubusercontent.com/u/38814188?v=4&s=36)](https://github.com/cotarr) [![](https://avatars.githubusercontent.com/u/33452?v=4&s=36)](https://github.com/pietia) [![](https://avatars.githubusercontent.com/u/818316?v=4&s=36)](https://github.com/bchew) [![](https://avatars.githubusercontent.com/u/8205343?v=4&s=36)](https://github.com/mattbaileyuk) [![](https://avatars.githubusercontent.com/u/20144632?s=36)](https://github.com/birdofpreyru)  
[\+ 原始贡献者 `csurf`](https://github.com/expressjs/csurf/graphs/contributors)

* * *

_这是原作的叉子 [库尔多夫](https://www.npmjs.com/package/csurf) 软件包被其作者以令人怀疑的推理而贬值(简言之,软件包是好的,但作者不想再维护它)。 向国家预防机制公布 [@pogodin/ csurf 医生 :](https://www.npmjs.com/package/@dr.pogodin/csurf)时,其版本 **1.11.0 国家** 完全匹配同样,最新版本的原始软件包,其版本始于 **1.12.0 国家** 将所有依赖性更新到最新版本,并根据需要进行错误维护。 从原始迁移 [库尔多夫](https://www.npmjs.com/package/csurf) 将所有提及改为 [@pogodin/ csurf 医生 :](https://www.npmjs.com/package/@dr.pogodin/csurf)。 。 。 ._

* * *

## 内容

-   [中国证监会](https://npmcn.com/package/%40dr.pogodin/csurf/#readme-csrf-demystified)
-   [安装](https://npmcn.com/package/%40dr.pogodin/csurf/#readme-installation)
-   [API 密码](https://npmcn.com/package/%40dr.pogodin/csurf/#readme-api)
-   [实例](https://npmcn.com/package/%40dr.pogodin/csurf/#readme-examples)
    -   [简单快递JS 示例](https://npmcn.com/package/%40dr.pogodin/csurf/#readme-simple-expressjs-example)
        -   [使用 AJAX](https://npmcn.com/package/%40dr.pogodin/csurf/#readme-using-ajax)
        -   [单页应用程序( SPA)](https://npmcn.com/package/%40dr.pogodin/csurf/#readme-single-page-application-spa)
    -   [忽略路线](https://npmcn.com/package/%40dr.pogodin/csurf/#readme-ignoring-routes)
    -   [自定义错误处理](https://npmcn.com/package/%40dr.pogodin/csurf/#readme-custom-error-handling)

## 中国证监会

**编程 [问题](https://owasp.org/www-community/attacks/csrf)** ——如果浏览器知道一个认证 用于您的域名的 cookie, 它可能会连同所有 HTTP( S) 请求一起发送给您 后端, 请检查,[页:1](https://npmcn.com/package/%40dr.pogodin/csurf/#readme-remark-01) 即使那些自动触发 完全不相关的网站;从而允许恶意第三方制作 代表用户向您的 API 认证的请求,如果他已经装入 页面进入他的浏览器( p)_即说._ 坏演员不必知道这些饼干, 它可能只是依赖于用户的浏览器自动、直接发送到 你的API).

页:1 如果你选择了这个 (单位:千美元)[`SameSite=None`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Set-Cookie#samesitesamesite-value) - 坏主意),或者你的用户使用过时的,奇怪的 浏览器,直到最近 [`SameSite=None`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Set-Cookie#samesitesamesite-value) 默认饼干设置 (单位:千美元)_譬如说._ [克罗姆把它改成了 `SameSite=Lax` 仅在2020年](https://developers.google.com/search/blog/2020/01/get-ready-for-new-samesitenone-secure)) (中文(简体) ). 当然,选择这种默认行为的人([`SameSite=None`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Set-Cookie#samesitesamesite-value)已经 之后又升到高级岗位 现在有六个数字教你 安全,而你们却陷于他们所造作的坑里_即说._ 他们选择 默认时,要铭记第三方 cookie 的应用程序,以及 他们没有想过这对可能的认证申请意味着什么 饼干).

**[防范企业社会责任基金的三个主要途径](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html)**, (中文(简体) ), 简言之,所有资料都证实发起人 HTTP( S) 请求是您网站在用户运行的一部分( 合法与否) 浏览器, _即说._ 它实际上能够读取(或写出)您的 cookie( 作为浏览器) 只允许前端访问来自同一来源的cookie). 请讲 hTTP( S) 请求中, 我们实际上假设您只使用 HTTP( S) —— 如果您 足够粗心 允许不安全的 HTTP 连接到你的后端, 你为什么关心CSRF?

-   [同步调试器模式](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#synchronizer-token-pattern) 方法包括服务器为当前用户生成随机符号 会话,将其存储在服务器侧并传递到前端 与 HTML 页面一起。 要进行 API 请求, 需要前端 以读取该标志,并作为请求的一部分将其传回服务器 有效载荷,或在其标题。 服务器比较收到的符号值和 请求到该用户会话后端存储的值,如果 证明请求发起人是页面的一部分,能够 以读取该来源的 Cookie 集,或该用户实际使用的 HTML . 当然,在您的页面中注入了恶意代码( Name[预算外](https://owasp.org/www-community/attacks/xss))将有能力 也一样,从而绕过你的CSRF保护, 但是如果你允许的话 因此,没有必要担心中国SRF的保护 无论有没有它,你都完蛋了.
    
    当无时, CSRF 保护模式由此库提供 [`cookie` 选项](https://npmcn.com/package/%40dr.pogodin/csurf/#readme-cookie) 已经设定。 执行起来也比较聪明, 而不是在服务器一侧存储发给用户的实际代币, 它生成,并为该用户存储随机密码密件 会话,然后用它来生成随机的,签名的符号,然后用它来生成 以 API 请求将这些指使符传递回服务器时验证 .
    
-   [自然双投递 Cookie 模式](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#naive-double-submit-cookie-pattern-discouraged) 方法包括服务器为当前用户生成随机符号 {\\fn黑体\\fs22\\bord1\\shad0\\3ahbe\\4ah00\\fscx67\\fscy66\\2chffffff\\3ch808080}然后把它传到前端 {\\fn黑体\\fs22\\bord1\\shad0\\3ahbe\\4ah00\\fscx67\\fscy66\\2chffffff\\3ch808080}你应该知道 _通过_ 饼干 做一个API 请求前端应该读取该符号,并将其传递回 服务器作为请求有效载荷的一部分,或在其标题中,而浏览器 在请求中还包括原始饼干。 服务器比较这些 两种符号值(在饼干中收到的,包含在 如果与请求的有效载荷或信头相符,则证明请求 发起者是页面的一部分,能够读取(或写)为此设定的饼干 源代码。 除了危险 [预算外](https://owasp.org/www-community/attacks/xss) 如果一个坏角色 控制(或 [预算外](https://owasp.org/www-community/attacks/xss)'es)是一个被保护域的子域,他将能够 打败它,因为他可以覆盖服务器为 保护域,从而绕过 CSRF 保护 请求自己的配对饼干(token)值.
    
    该库在 页:1 [`cookie` 选项](https://npmcn.com/package/%40dr.pogodin/csurf/#readme-cookie) 设定 `true`此外,它也得到了一定的执行 不同的是,重复使用前一种模式所用的同一种代码和逻辑—— 它为用户会话产生随机的秘密(虽然它不是一个相当的秘密, 它不一定要在这个情景中,然后生成匹配的随机 代号,由那个秘密签名, 它把它们都送到前端 _通过_ 两个不同的饼干。 要提出请求,前端应读作 这些饼干中的一款, 并把它纳入请求的有效载荷, 或标题。 收到请求时,服务器将确认收到该信使 在请求的有效载荷(标题)中,由所收到的秘密签名 _通过_ 相应的饼干。 再说一遍,这个支票根本不靠这个 “秘密”是秘密,它只是在乎 是否“秘密” 和标志是匹配的对或不匹配的——它提供相同的 保护,如果前端刚刚通过 请求的“秘密” 值本身,直接与其在饼干中的值进行比较.
    
-   [已签名的双投递 Cookie](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#signed-double-submit-cookie-recommended) 方法基本相同,但需要带符号的饼干 将在服务器侧签名和验证。 这样,即使一个坏演员 控制子域,从而能够覆盖符号饼干 ,它将被服务器检测到.
    
    该库在 页:1 [`cookie` 选项](https://npmcn.com/package/%40dr.pogodin/csurf/#readme-cookie) 设置为带有 cookie 配置的对象 能够签署(`signed` 旗帜)。 由于执行的方式 (请求中的符号与存储在 其中一个饼干,其实是需要签名和防护的 对“秘密”饼干的修改 [`cookie` 选项](https://npmcn.com/package/%40dr.pogodin/csurf/#readme-cookie) 实际应用。 而且,作为前端 不需要知道"秘密"发送请求, 选择也没用 [`HttpOnly`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Set-Cookie#httponly), (中文(简体) ), `secure`和其他安全选项,尽管它并不完全 与这种保护方式有关.
    

**剧情** a. 索赔的前后 [库尔多夫](https://www.npmjs.com/package/csurf) 库开始于 [“中国社会风险基金在大众社会风险保险一揽子方案中的脆弱性”](https://fortbridge.co.uk/research/a-csrf-vulnerability-in-the-popular-csurf-package)。 。 。 . 问题是,安全“专家”写它并不完全 既不理解CSRF的保护,也不理解JavaScript,所以他才刚刚变得困惑 关于图书馆实施细节,请在上文作简要解释 基本上,他主张,只要简单 `cookie: true` 设置库 未正确执行 [已签名的双投递 Cookie](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#signed-double-submit-cookie-recommended) 保护,因为它没有在它设定的饼干上签名, 它没有保护 它不检查饼干的值 在随后的 API 请求中表示符号 。 的确,由于这种设定是正确的 执行 [直肠双投饼干](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#naive-double-submit-cookie-pattern-discouraged) 保护,其局限性不影响大多数简单的网站.

这篇文章最后以一个误导性的说法结尾,图书开发者承认 并且因为它而使图书馆贬值 gitHub repo 中注解为“”_由于 收到的大量安全脆弱性报告,其中大多数是: 利用公司社会责任基金本身的根本局限性。 捷运.js 项目没有资源投入这一模块,这主要是: 对现代基于SPA的应用来说是不必要的._\- 基本上说 说"图书馆没事,但我们不想花时间回信" 给每个抱怨图书馆弱点的白痴,没有 理解这件事情.

在现实中,最危险的时刻是.. 鼓励原图书库,并重新播放关于互联网的文章 开发者从这个长期存在的 CSURF 库切换到许多新库之一 CSRF - 保护图书馆 由不同的人从头写作(他们不) 因此,你猜他们的能力水平 (见本主题)。 这都为依赖中毒创造了机会 (单位:千美元)_即说._ 有人用恶意代码创建了新的 CSRF 保护库 )或对诚实的错误(肯定的是,这个长期常设的图书馆 与任何新的替代方案相比. 这就是为什么这个叉 最初的CSURF 诞生—— 相反 我用新的替代品来尝试我的运气, 我刚刚造出了这个时间证明的图书馆, 审查了它的代码,以防万一,更新了依赖关系,并转换了源 代码库为TypeScript(只是为了便于未来的维护). 项目是 开放源码,因此,欢迎大家进一步审查,并提出任何建议 改进或修正.

## 安装

需要一个会话中间软件或 [饼干派瑟](https://www.npmjs.com/package/cookie-parser) 将首先初始化.

-   如果你正在设置 ["饼干"选项](https://npmcn.com/package/%40dr.pogodin/csurf/#readme-cookie) 对非`false` 数值, 那你必须用 [饼干派瑟](https://www.npmjs.com/package/cookie-parser) 在本模块之前.
-   否则, 您必须在此模块之前使用会话中间软件 。 例如:
    -   [专会](https://www.npmjs.com/package/express-session)
    -   [饼干会话](https://www.npmjs.com/package/cookie-session)

如果您对如何执行此模块有疑问, 请读 : [理解企业社会责任基金](https://github.com/pillarjs/understanding-csrf)。 。 。 .

这是一个 [节点.js](https://nodejs.org/en/) 模块 [npm 登记](https://www.npmjs.com/)。安装使用 [`npm install` 命令](https://docs.npmjs.com/getting-started/installing-npm-packages-locally)数字 :

```shell
$ npm install --save @dr.pogodin/csurf
```

## API 密码

```js
import csurf from '@dr.pogodin/csurf';
```

### csurf(\[选项\])

为 CSRF 符号创建和验证创建中间软件 。 这个中间软件 添加a `req.csrfToken()` 函数来制作一个符号,该符号应当添加到 请求在隐藏窗体字段、查询字符串等内进行变异. 此标志是针对访客的会话或csrf cookie验证的.

#### 选项

这个 `csurf` 函数选择 `options` 可能包含的对象 下列任何一键:

##### 饼干

确定用户的令牌秘密是否应该存储在饼干中 或进入 `req.session`. 将标志性的秘密放入饼干工具 页:1 [双重提交 cookie 模式](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#signed-double-submit-cookie-recommended)。 。 。 . 默认为 `false`。 。 。 .

设定为 `true` (或饼干的选项对象),然后是模块 改变行为而不再使用 `req.session`这意味着你 _没有 更长时间使用会话中间软件_相反,你确实需要使用 [饼干派瑟](https://www.npmjs.com/package/cookie-parser) 中间软件 你的应用程序在这中间软件之前.

当设定到对象时,可以启用密钥的 cookie 存储和 对象包含此功能的选项( 当设定为 `true`,则 使用选项的默认值)。 备选方案可包含其中任何一项 以下键 :

-   `key` - 用于存储象征秘密的饼干名称 (违约) `'_csrf'`) (中文(简体) ).
-   `path` - 饼干的路径(默认为 `'/'`) (中文(简体) ).
-   `signed` - 表示是否应该签名(默认为: `false`) (中文(简体) ).
-   `secure` - 标记只用于 HTTPS 的饼干( 默认为 `false`) (中文(简体) ).
-   `maxAge` - 饼干过期的秒数 (默认会话长度).
-   `httpOnly` - 标记饼干,只供网络服务器访问 (违约) `false`) (中文(简体) ).
-   `sameSite` - 为饼干设置相同的站点策略( 默认为) `false`) (中文(简体) ). 这可以设定为 `'strict'`, (中文(简体) ), `'lax'`, (中文(简体) ), `'none'`,或 `true` (地图到 `'strict'`) (中文(简体) ).
-   `domain` - 设置 cookie 有效的域名( 默认为当前) 页:1.

##### 忽略方法

CSRF 符号检查将禁用的一系列方法 . 默认为 `['GET', 'HEAD', 'OPTIONS']`。 。 。 .

##### 忽略请求

带有标志的可选函数 `(req: Request) => boolean`。 。 。 . 如果提供了, 则每个导致此结果的请求都会跳过 CSRF 令牌检查 要返回的函数 _真实_。 。 。 .

##### 会话

确定哪些属性(“ 键 ”) `req` 会话对象位于此处. 默认为 `'session'` (即观察) `req.session`) (中文(简体) ). 中国证监会的秘密 从此库存储并读取为 `req[sessionKey].csrfSecret`。 。 。 .

如果 ["饼干"选项](https://npmcn.com/package/%40dr.pogodin/csurf/#readme-cookie) 没有 `false`,然后此选项会 没什么.

##### 价值

提供中间软件将引用的函数,以读取从 请求审定。 该功能称为 `value(req)` 已经 以字符串的形式返回符号 .

默认值是读取符号的函数 : 地点,顺序:

-   `req.body._csrf` - 通常由 `body-parser` 模块.
-   `req.query._csrf` 从 Express.js 读取 URL 的内置 查询字符串.
-   `req.headers['csrf-token']` - 那个 `CSRF-Token` HTTP 请求头 .
-   `req.headers['xsrf-token']` - 那个 `XSRF-Token` HTTP 请求头 .
-   `req.headers['x-csrf-token']` - 那个 `X-CSRF-Token` HTTP 请求头 .
-   `req.headers['x-xsrf-token']` - 那个 `X-XSRF-Token` HTTP 请求头 .

## 实例

### 简单快递JS 示例

以下是一些生成窗体的服务器侧代码的示例 这需要一个CSRF的标志 发回.

```js
import cookieParser from 'cookie-parser';
import csrf from '@dr.pogodin/csurf';
import bodyParser from 'body-parser';
import express from 'express';

// setup route middlewares
const csrfProtection = csrf({ cookie: true })
const parseForm = bodyParser.urlencoded({ extended: false })

// create express app
const app = express()

// parse cookies
// we need this because "cookie" is true in csrfProtection
app.use(cookieParser())

app.get('/form', csrfProtection, function (req, res) {
  // pass the csrfToken to the view
  res.render('send', { csrfToken: req.csrfToken() })
})

app.post('/process', parseForm, csrfProtection, function (req, res) {
  res.send('data is being processed')
})
```

视图内部( 取决于模板语言; 手提栏样式) ),设置 `csrfToken` 值为隐藏的值 命名输入字段 `_csrf`数字 :

```html
<form action="/process" method="POST">
  <input type="hidden" name="_csrf" value="{{csrfToken}}">
  
  Favorite color: <input type="text" name="favoriteColor">
  <button type="submit">Submit</button>
</form>
```

#### 使用 AJAX

当通过 ajax 访问受保护的路由时, csrf 符号需要为 在请求中通过。 通常使用请求页眉进行, 如添加 请求信头通常可以在中心位置进行,而不需要 有效载荷修改.

中国证监会的令牌来自 `req.csrfToken()` 呼叫服务器侧. 这个信使需要暴露在客户端,一般通过将其包含在 初始页面内容。 一种可能性是在 HTML 中存储 `<meta>` 标签, ,然后在 JavaScript 请求时检索到值.

以下内容可以包含在您的观点中(下面的手列示例),其中 `csrfToken` 值来自 `req.csrfToken()`数字 :

```html
<meta name="csrf-token" content="{{csrfToken}}">
```

下面是使用下列方法的例子: [获取 API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) 员额 页:1 `/process` 带有 CSRF 符号的路由 `<meta>` 页面标签 :

```js
// Read the CSRF token from the <meta> tag
var token = document.querySelector('meta[name="csrf-token"]').getAttribute('content')

// Make a request using the Fetch API
fetch('/process', {
  credentials: 'same-origin', // <-- includes cookies in the request
  headers: {
    'CSRF-Token': token // <-- is the csrf token as a header
  },
  method: 'POST',
  body: {
    favoriteColor: 'blue'
  }
})
```

#### 单页应用程序( SPA)

许多SPA框架如Angular有CSRF支持自动构建. 通常它们会反映 特定饼干的价值,比如 `XSRF-TOKEN` (此为角相也.

为了利用这一点,设定值来自 `req.csrfToken()` 在饼干中 由SPA框架使用。 只要在这条路线上 制作页面( 在 `res.render` 或者说 `res.sendFile` 在"快车"里叫着, (例如,a/cn.9/wg.iii/wp.iii/wp.1号文件).

以下是典型SPA反应的快递:

```js
app.all('*', function (req, res) {
  res.cookie('XSRF-TOKEN', req.csrfToken())
  res.render('index')
})
```

### 忽略路线

**说明** CSRF 检查应只针对您期望的请求而禁用 来源于您的网站。 不禁用 CSRF 检查请求 您希望只来自您的网站。 现有会话,即使 它属于经认证的用户,不足以防范CSRF 攻击.

以下是如何命令您的路线的示例, 这样某些端点 不检查有效的 CSRF 令牌 .

```js
import cookieParser from 'cookie-parser';
import csrf from '@dr.pogodin/csurf';
import bodyParser from 'body-parser';
import express from 'express';

// create express app
const app = express()

// create api router
const api = createApiRouter()

// mount api before csrf is appended to the app stack
app.use('/api', api)

// now add csrf and other middlewares, after the "/api" was mounted
app.use(bodyParser.urlencoded({ extended: false }))
app.use(cookieParser())
app.use(csrf({ cookie: true }))

app.get('/form', function (req, res) {
  // pass the csrfToken to the view
  res.render('send', { csrfToken: req.csrfToken() })
})

app.post('/process', function (req, res) {
  res.send('csrf was required to get here')
})

function createApiRouter () {
  const router = new express.Router()

  router.post('/getProfile', function (req, res) {
    res.send('no csrf to get here')
  })

  return router
}
```

### 自定义错误处理

当 CSRF 令牌验证失败时, 就会出现错误 `err.code === 'EBADCSRFTOKEN'`。这可用于显示自定义 错误消息 .

```js
import bodyParser from 'body-parser';
import cookieParser from 'cookie-parser';
import csrf from '@dr.pogodin/csurf';
import express from 'express';

const app = express()
app.use(bodyParser.urlencoded({ extended: false }))
app.use(cookieParser())
app.use(csrf({ cookie: true }))

// error handler
app.use(function (err, req, res, next) {
  if (err.code !== 'EBADCSRFTOKEN') return next(err)

  // handle CSRF token errors here
  res.status(403)
  res.send('form tampered with')
})
```

## 常见问题

### @dr\.pogodin/csurf 是什么？

ExpressJS 的 CSRF 代号中间软件

### 如何安装 @dr\.pogodin/csurf？

在项目目录运行 npm install @dr\.pogodin/csurf，或使用 pnpm add / yarn add / bun add。

### @dr\.pogodin/csurf 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @dr\.pogodin/csurf 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @dr\.pogodin/csurf 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=22。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @dr\.pogodin/csurf 可以商用吗？

@dr\.pogodin/csurf 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @dr\.pogodin/csurf 的下载量有多少？

根据 npm 官方下载统计，@dr\.pogodin/csurf 在 2026/10/13 – 2026/11/11 这 30 天内被下载 76,717 次，日均约 2,557 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @dr\.pogodin/csurf 还在维护吗？

最新版本 1\.18\.2 发布于 2026/10/15（29 天前）；至今共发布 25 个版本，其中过去 12 个月发布了 7 个；首次发布于 2022/11/05。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

