How to add cors settings (origin)?
Describe the feature
At the moment I have the following rule in my nitro.config.ts:
routeRules: {
'/**': {
cors: true,
},
},
I want to only accept cors for my website-domain (prod and dev). How can I make options like cors origin in Nitro? Unfortunately the whole cors topic is not covered in the docs.
E.g. my domain is www.example.com and my api is at api.example.com -> Without cors: true this results in errors.
Reference
- Express CORS options: https://github.com/expressjs/cors#configuration-options
- Fastify CORS options: https://github.com/fastify/fastify-cors?tab=readme-ov-file#options
Additional information
- [ ] Would you be willing to help implement this feature?
This should help, https://github.com/nitrojs/nitro/issues/539
Official docs for routeRules shows how to handle special routes in dev or prod individually: https://nitro.build/config#routerules
You could use devProxy, if I understand correctly what you want to achieve on localhost:
{
devProxy: {
'/proxy/test': 'http://localhost:3001',
'/proxy/example': { target: 'https://example.com', changeOrigin: true }
}
I have no problem making a differntiation between dev and prod. I want to set cors origin to a specific URL instead of accepting all origins.
For example in Express cors has an options attribute where you can set origin and other things. You could even use an async function for this:
var corsOptions = {
origin: function (origin, callback) {
db.loadOrigins(function (error, origins) {
callback(error, origins)
})
}
}
app.use(cors(corsOptions));
What I am looking for is something like this:
routeRules: {
'/**': {
cors: {
origin: 'www.example.com'
},
},
},
I think we can have a Fastify-like configuration for CORS. Currently, I am setting up the CORS configuration through a middleware, which, in my opinion, isn't the best approach. I propose to have something like this:
interface NitroCorsOptions {
origin?: string | string[];
credentials?: boolean;
exposedHeaders?: string | string[];
allowedHeaders?: string | string[];
methods?: string | string[];
maxAge?: number;
preflightContinue?: boolean;
optionsSuccessStatus?: number;
preflight?: boolean;
strictPreflight?: boolean;
}
If @pi0 agrees on this. I can help implement.
I was just wondering if this actually needs to be done within H3?
Just to note a workaround for now: Cors cant be configured by nitro.config.ts (what this issue is about), but it can be configured by use of a middleware, e.g. here is what I came up with that works with dev and prod:
1.cors.ts
import {
defineEventHandler,
getHeader,
isMethod,
setHeader,
setResponseStatus,
} from 'h3';
import { useRuntimeConfig } from 'nitropack/runtime';
export default defineEventHandler((event) => {
const { frontendUrl } = useRuntimeConfig();
const origin = getHeader(event, 'origin');
if (origin === frontendUrl) {
setHeader(event, 'Access-Control-Allow-Origin', origin);
setHeader(event, 'Vary', 'Origin');
setHeader(
event,
'Access-Control-Allow-Methods',
'GET, POST, PUT, PATCH, DELETE, OPTIONS',
);
setHeader(event, 'Access-Control-Allow-Credentials', 'true');
setHeader(event, 'Access-Control-Allow-Headers', 'Content-Type, Authorization');
}
// Short-circuit preflight requests
if (isMethod(event, 'OPTIONS')) {
setResponseStatus(event, 204);
return {};
}
});