通过 100+ 个技巧学习 Nuxt!

csurf
nuxt-csurf

Nuxt 的跨站请求伪造 (CSRF) 防护

nuxt-oa-social-card

npm versionnpm downloadsLicenseNuxt

Nuxt Csurf

跨站请求伪造 (CSRF) 防护。
创建用于 CSRF 令牌创建和验证的中间件。

✅ 支持 Node.js 服务器和无服务器环境
✅ 支持通用渲染和客户端渲染 (ssr: true|false)
✅ 每个路由配置
✅ TypeScript
❌ 由于某些限制,不支持静态托管和 nitro 预渲染 *

安装

npx nuxi@latest module add csurf

全局配置

// nuxt.config.js
export default defineNuxtConfig({
  modules: ['nuxt-csurf'],
  csurf: { // optional
    https: false, // default true if in production
    cookieKey: '', // "__Host-csrf" if https is true otherwise just "csrf"
    cookie: { // CookieSerializeOptions from unjs/cookie-es
      path: '/',
      httpOnly: true,
      sameSite: 'strict'
    },
    methodsToProtect: ['POST', 'PUT', 'PATCH'], // the request methods we want CSRF protection for
    encryptSecret: /** a 32 bits secret */, // for stateless server (like serverless runtime), random bytes by default
    encryptAlgorithm: 'aes-256-cbc', // by default 'aes-256-cbc' (node), 'AES-CBC' (serverless)
    addCsrfTokenToEventCtx: true, // default false, to run useCsrfFetch on server set it to true
    headerName: 'csrf-token' // the header where the csrf token is stored
  } 
})

每个路由配置

要启用每个路由配置,请使用如下 routeRules

export default defineNuxtConfig({
  routeRules: {
    '/api/nocsrf': {
      csurf: false
    },
    '/api/test': {
      csurf: {
        methodsToProtect: ['POST'] // protect POST request only
      }
    }
  }
})

useCsrfFetch

此组合项为 useFetch 提供了便捷的封装。它会自动在标头中添加 CSRF 令牌。

const { data, pending, error, refresh } = useCsrfFetch('/api/login', { query: param1: 'value1' })

$csrfFetch

此助手为 $fetch 提供了便捷的封装。它会自动在标头中添加 CSRF 令牌。

const { $csrfFetch } = useNuxtApp()
const { data } = await $csrfFetch('/api/login', { method: 'POST', body:, headers:})

useCsrf

如果你需要访问 CSRF 令牌值,请使用此组合项。

const { csrf } = useCsrf()
console.log(csrf) // something like: mo4+MrFaeXP7fhAie0o2qw==:tLUaqtHW6evx/coGQVAhtGAR+v6cxgFtrqmkOsuAMag8PHRnMwpbGGUO0TPJjL+4

在 localhost 上尝试生产环境 (yarn preview)

NITRO_CSURF_HTTPS=false
NITRO_CSURF_COOKIE_KEY=csrf

局限性

CSRF 令牌值存储在 DOM 中,如 OWASP 的 CSRF 防护备忘单中所述。因此,对于每个新的页面请求,都必须生成 DOM,这对于静态站点(或预渲染路由)来说并非如此。请参阅错误 #42

鸣谢