-
Notifications
You must be signed in to change notification settings - Fork 540
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cors
route rule should auto response to preflight
#2340
Comments
Hi @pi0 @danielroe , I digged deeper into this and found a critical bug with route rules not beeing applied. Maybe a problem with https://github.com/unjs/radix3? The following rule works for all routes:
BUT if a route does not have GET route, the routeRoule is not applied. E.g.:
Therefor the routes without a GET route throw a cors error in my case. This could also explain nuxt/nuxt#25686 I made a reproduction repo, you can simply run |
cors: true
does not work
It gets even more weird! The route rules are applied if there is a GET route, e.g. Route rule applied for POST route: // contact.ts
export default defineEventHandler(async (event) => {
return '404';
}); Route rule NOT applied for POST route: // contact.ts
export default defineEventHandler(async (event) => {
throw createError({
statusCode: 404,
});
}); |
This is insane. I spent the last 8 hours trying to figure out what was going on with my CORS headers not being set. I added a GET route and it fixed all of my problems. I'm genuinely regretting using nitro. I don't quite understand how you were able to figure this out but big shout out to @MickL for saving my work project. |
Possibly related to #1806 |
This is definitely a critical bug and an annoying one as well. Maybe it will be fixed with v3? @pi0 But in any case it needs to be fixed for v2 aswell. This also makes problems within Nuxt: nuxt/nuxt#25686 |
cors
route rule isn't effective if there is no GET handler
I have created a better sandbox to show Nitro behavior: https://stackblitz.com/edit/github-mdtiap?file=server%2Froutes%2Fapi%2Ftest.post.ts (update: you need to run it locally and use Nitro actually do apply route rules to all methods regardless if there is a handler registered for them or not. (notice that there are cors headers to the post-only API route's response). The issue is how CORS preflight works in browsers. Browsers use an I understand it can be frustrating with CORS issues but it isn't a bug at least with how route rules work. (...so what we can improve...) I understand DX is not good and CORS issues, god knows how much frustration they cause every developer, and that when Nitro allows to set a magical route rule We can improve our route rule handler to auto-respond to OPTIONS even if there is not a handler but the problem is that it is too soon. Route rules are applied before any of the user handlers and if a user wants to actually handle OPTIONS method of a path (to apply their security policy -- the very purpose of CORS functionality) nitro will implicitly override this. So while it might look like an easy fix/feature, it might cause security implications which are worst than a not working CORS call when it matters. I will be thinking about how we can safely implement this as a fallback approach (nitro error handler could be one place, by checking cors route rule) but i think one first and good step is that we at least document this: CORS functionality needs API handlers to respond to OPTIONS requests and as a userland solution, one can add
|
cors
route rule isn't effective if there is no GET handlercors
route rule should auto response to preflight
@ArcherScript Preflight request is not GET, it is OPTIONS. I suggest you read MDN docs about Preflight request and CORS mechanism first. Adding Browsers expect to have an "ok" response when they want to verify CORS (via OPTIONS fetch). If there is no event handler, Nitro (your application), responds with 404 or 405 both unacceptable by browsers. You can alternatively use |
Yeah this is what I thought. Thanks for the explanation. It seems like I understand why it is that way though from the explanation. |
Should we expand the documentation on |
Surely feel free to contribute to h3 docs if you could successfully use it 🙏🏼 jsdocs is here. Mind you, nitro route rules cors handler does not use h3 utility btw. it uses simple headers (why? because it can be natively applied to deployment provider route rules). I think we might also add a new |
One thing is CORS but this issue actually turned out to a critical bug. Maybe it was not clear enough in the end but it took me some time to figure it out: Route roules are not applied if a route does not have a GET route. For example:
Or did I miss something? This should be visible in my repo: https://github.com/MickL/nitro-route-rules-bug |
@MickL please locally run my reproduction from #2340 (comment). Route rules always apply regardless of the incoming request method or if even there is a matching router handler or not. route rule runs on its own. CORS fails in your example not because the rule |
But why does it work when adding the get route? Like for PATCH /products it works in my example. Sorry if I miss something.
If I would add an /items.ts that returns just an empty string it would work for PATCH items aswell. |
The browser makes a preflight to the same path with OPTIONS method to check cors. It expects:
route rules add cors headers (1), you need to do (2) by adding any kind of catch-all handler that simply gives that "ok". Please read about Preflight request and CORS mechanism. Next steps:
|
I see, thanks for all the explanations! |
@pi0 Is there any update on this issue? I didnt find anything about cors in the docs yet. Is the only workaround to add empty route handlers atm or did anything change with the underlying UnJS packages and/or Nitro v3? Atm the/my workaround is to place this in every position where I dont have a GET route. And the file is not there the other routes wont work (high risk!): export default defineEventHandler(async (event) => {
if (event.method !== 'OPTIONS') {
throw createError({
status: 404,
});
}
}); |
Another issue with this is that non-existent routes return cors error instead of 404. |
Environment
Reproduction
https://stackblitz.com/edit/github-xaqmuq?file=nitro.config.ts
Describe the bug
Setting
cors: true
to does not work:The browser still throws cors error:
With header, too:
Error:
Additional context
I already opened an issue at Nuxt that setting
corse:true
does not have an effect on/api
routes, only on/public
folder.Logs
No response
The text was updated successfully, but these errors were encountered: