CSRF 保护
此中间件通过检查 Origin 标头和 Sec-Fetch-Site 标头来防止 CSRF 攻击。如果任一验证通过,则允许请求。
该中间件仅验证以下请求:
- 使用不安全的 HTTP 方法(非 GET、HEAD 或 OPTIONS)
- 具有 HTML 表单可以发送的内容类型(
application/x-www-form-urlencoded、multipart/form-data或text/plain)
不发送 Origin 标头的旧浏览器,或使用反向代理移除这些标头的环境,可能无法正常工作。在此类环境中,请使用其他 CSRF 令牌方法。
导入
ts
import { Hono } from 'hono'
import { csrf } from 'hono/csrf'用法
ts
const app = new Hono()
// 默认:同时验证 origin 和 sec-fetch-site
app.use(csrf())
// 允许特定的来源
app.use(csrf({ origin: 'https://myapp.example.com' }))
// 允许多个来源
app.use(
csrf({
origin: [
'https://myapp.example.com',
'https://development.myapp.example.com',
],
})
)
// 允许特定的 sec-fetch-site 值
app.use(csrf({ secFetchSite: 'same-origin' }))
app.use(csrf({ secFetchSite: ['same-origin', 'none'] }))
// 动态 origin 验证
// 强烈建议验证协议以确保匹配到 `$`。
// 你绝不应该*进行前向匹配。
app.use(
'*',
csrf({
origin: (origin) =>
/https:\/\/(\w+\.)?myapp\.example\.com$/.test(origin),
})
)
// 动态 sec-fetch-site 验证
app.use(
csrf({
secFetchSite: (secFetchSite, c) => {
// 始终允许同源
if (secFetchSite === 'same-origin') return true
// 允许 webhook 端点的跨站请求
if (
secFetchSite === 'cross-site' &&
c.req.path.startsWith('/webhook/')
) {
return true
}
return false
},
})
)选项
可选 origin: string | string[] | Function
指定 CSRF 保护允许的来源。
string:单个允许的来源(例如'https://example.com')string[]:允许的来源数组Function:自定义处理函数(origin: string, context: Context) => boolean,用于灵活的来源验证和绕过逻辑
默认:仅与请求 URL 同源
函数处理程序接收请求的 Origin 标头值和请求上下文,允许基于请求属性(如路径、标头或其他上下文数据)进行动态验证。
可选 secFetchSite: string | string[] | Function
指定 CSRF 保护允许的 Sec-Fetch-Site 标头值,使用 Fetch Metadata。
string:单个允许的值(例如'same-origin')string[]:允许的值数组(例如['same-origin', 'none'])Function:自定义处理函数(secFetchSite: string, context: Context) => boolean,用于灵活验证
默认:仅允许 'same-origin'
标准 Sec-Fetch-Site 值:
same-origin:来自同源的请求same-site:来自同一站点的请求(不同子域)cross-site:来自不同站点的请求none:非来自网页的请求(例如浏览器地址栏、书签)
函数处理程序接收请求的 Sec-Fetch-Site 标头值和请求上下文,支持基于请求属性进行动态验证。