Nuxt Csurf
クロスサイトリクエストフォージェリ(CSRF)対策。
CSRFトークンの生成と検証のためのミドルウェアを作成します。
✅ Node.jsサーバーとサーバーレス環境をサポート
✅ ユニバーサルレンダリングとクライアントサイドレンダリングの両方をサポート(ssr: true|false
)
✅ ルートごとの設定
✅ TypeScript
❌ 静的ホスティングとnitro prerenderは、特定の制限によりサポートしていません *
インストール
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トークンの値は、OWASPのCSRFチートシートに記載されているように、DOMに格納されます。そのため、静的サイト(またはプリレンダリングされたルート)のように、すべてのページリクエストでDOMを生成する必要はありません。エラー#42を参照してください。
クレジット
- tiny-csrf と expressjs/csurfに触発されました
- OWASP CSRFチートシートを参照