Skip to content

Commit 2e093cc

Browse files
committed
feat: ✨ option to configure header name
Resolves #38
1 parent 1c3073b commit 2e093cc

File tree

7 files changed

+19
-10
lines changed

7 files changed

+19
-10
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ export default defineNuxtConfig({
3737
methodsToProtect: ['POST', 'PUT', 'PATCH'], // the request methods we want CSRF protection for
3838
encryptSecret: /** a 32 bits secret */, // only for non serverless runtime, random bytes by default
3939
encryptAlgorithm: 'aes-256-cbc', // by default 'aes-256-cbc' (node), 'AES-CBC' (serverless)
40-
addCsrfTokenToEventCtx: true // default false, to run useCsrfFetch on server set it to true
40+
addCsrfTokenToEventCtx: true, // default false, to run useCsrfFetch on server set it to true
41+
headerName: 'csrf-token' // the header where the csrf token is stored
4142
}
4243
})
4344
```

playground/nuxt.config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export default defineNuxtConfig({
1515
},
1616
csurf: {
1717
https: process.env.NODE_ENV === 'production',
18-
methodsToProtect: ['POST']
18+
methodsToProtect: ['POST'],
19+
headerName: 'X-CSRF-TOKEN'
1920
}
2021
})

src/module.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export default defineNuxtModule<ModuleOptions>({
1717
httpOnly: true,
1818
sameSite: 'strict'
1919
},
20+
headerName: 'csrf-token',
2021
methodsToProtect: ['POST', 'PUT', 'PATCH']
2122
},
2223
setup (options, nuxt) {
@@ -31,6 +32,7 @@ export default defineNuxtModule<ModuleOptions>({
3132
}
3233

3334
nuxt.options.runtimeConfig.csurf = defuReplaceArray(nuxt.options.runtimeConfig.csurf, { ...options })
35+
nuxt.options.runtimeConfig.public.csurf = { headerName: nuxt.options.runtimeConfig.csurf.headerName }
3436

3537
if (options.enabled !== false) {
3638
addServerHandler({ handler: resolve('runtime/server/middleware/csrf') })
@@ -54,6 +56,9 @@ declare module 'nuxt/schema' {
5456
interface RuntimeConfig {
5557
csurf: ModuleOptions
5658
}
59+
interface PublicRuntimeConfig {
60+
csurf: Pick<ModuleOptions, 'headerName'>
61+
}
5762
}
5863

5964
declare module 'nitropack' {

src/runtime/composables.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Adapted from https://github.com/nuxt/nuxt/blob/7046930a677f4c987afaee5a0165841b0e0a517f/packages/nuxt/src/app/composables/fetch.ts
2-
import { useFetch, type FetchResult, type UseFetchOptions, useNuxtApp } from '#app'
2+
import { useFetch, type FetchResult, type UseFetchOptions, useNuxtApp , useRuntimeConfig } from '#app'
33
import type { Ref } from 'vue'
44
import type { FetchError } from 'ofetch'
55
import type { NitroFetchRequest, AvailableRouterMethod as _AvailableRouterMethod } from 'nitropack'
@@ -49,9 +49,9 @@ export function useCsrfFetch<
4949
arg2?: string
5050
) {
5151
const [opts = {}, autoKey] = typeof arg1 === 'string' ? [{}, arg1] : [arg1, arg2]
52-
const { csrf } = useCsrf()
52+
const { csrf, headerName } = useCsrf()
5353
opts.headers = (opts.headers || {}) as Record<string, string>
54-
opts.headers['csrf-token'] = csrf // add csrf token to req headers
54+
opts.headers[headerName] = csrf // add csrf token to req headers
5555
return useFetch<ResT, ErrorT, ReqT, Method, _ResT, DataT, PickKeys, DefaultT>(
5656
request,
5757
opts,
@@ -111,9 +111,10 @@ export function useLazyCsrfFetch<
111111
}
112112

113113
export function useCsrf() {
114+
const headerName = useRuntimeConfig().public.csurf.headerName ?? ''
114115
if (import.meta.server) {
115-
return { csrf: useNuxtApp().ssrContext?.event?.context?.csrfToken }
116+
return { csrf: useNuxtApp().ssrContext?.event?.context?.csrfToken, headerName }
116117
}
117118
const metaTag = window.document.querySelector('meta[name="csrf-token"]')
118-
return { csrf: metaTag?.getAttribute('content') }
119+
return { csrf: metaTag?.getAttribute('content'), headerName }
119120
}

src/runtime/plugin.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ type MappedType<R extends ResponseType, JsonType = any> = R extends keyof Respon
1515
type $CsrfFetch = <T = any, R extends ResponseType = "json">(request: FetchRequest, options?: FetchOptions<R>, fetch?: $Fetch) => Promise<MappedType<R, T>>
1616

1717
export default defineNuxtPlugin(() => {
18-
const { csrf } = useCsrf()
18+
const { csrf, headerName } = useCsrf()
1919
const csrfFetch: $CsrfFetch = (request, options, fetch = $fetch) => {
2020
if (!options) { options = {} }
2121
options.headers = (options.headers || {}) as Record<string, string>
22-
options.headers['csrf-token'] = csrf
22+
options.headers[headerName] = csrf
2323
return fetch(request, options)
2424
}
2525
return {

src/runtime/server/middleware/csrf.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export default defineEventHandler(async (event) => {
1717
if (!methodsToProtect.includes(method)) { return }
1818

1919
const secret = getCookie(event, csrfConfig.cookieKey!) ?? ''
20-
const token = getHeader(event, 'csrf-token') ?? ''
20+
const token = getHeader(event, baseConfig.headerName!) ?? ''
2121
// verify the incoming csrf token
2222
const isValidToken = await csrf.verify(secret, token, await useSecretKey(csrfConfig), csrfConfig.encryptAlgorithm)
2323
if (!isValidToken) {

src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ export interface ModuleOptions {
2323
encryptAlgorithm?: EncryptAlgorithm
2424
addCsrfTokenToEventCtx?: boolean // to run useCsrfFetch on server
2525
enabled?: boolean // disabled module server middleware/plugin when `enabled` is set to `false` (you will still have access to `useCsrf`/`useCsrfFetch` client composables)
26+
headerName?: string
2627
}

0 commit comments

Comments
 (0)