Skip to content
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 is not working with non GET methods #1806

Closed
Ibz786 opened this issue Oct 7, 2023 · 7 comments
Closed

CORS is not working with non GET methods #1806

Ibz786 opened this issue Oct 7, 2023 · 7 comments
Labels
bug Something isn't working cors nuxt reproduction

Comments

@Ibz786
Copy link

Ibz786 commented Oct 7, 2023

Hi guys,

I've been stuck on an issue for the longest time and have tried everything I can think of, but can't seem to figure out the problem

I have a Vue 3 app (localhost:3000) and a Nuxt 3 app, using Nitro (localhost:3500)

In Nuxt/Nitro, I have created some server/api routes, which I'm trying invoke from my Vue 3 application, via Axios (using withCredentials)

I've set up some basic CORS configuration, and when it comes to simple GET methods, all works fine. However when it comes to POST, I get a POST + Preflight issue as follows:

Access to XMLHttpRequest at 'http://localhost:3500/api/v1/auth/login' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

I've tried many ways to setup CORs from middleware, to routeRules and now I've just tried using nuxt-security module, but unfortunately, no difference

My code is as follows:
Vue 3:

// api.service.js
import axios from 'axios';

export default axios.create({
    baseURL: 'http://localhost:3500/api/v1/',
    withCredentials: true
});
// books.service.js
import ApiService from './api.service';

async function geFilms (payload) {
    const response = await ApiService.get('films');
    // ... do stuff
}
// auth.service.js
import ApiService from './api.service';

async function login (payload) {
    const response = await ApiService.post('auth/login', payload);
    // ... do stuff
}

Nuxt 3 / Nitro:
GET method example works fine

// server/api/v1/films- index.get.ts
export default defineEventHandler(async (event) => {
    console.log('this is films:get!')
});

POST example doesn't work

// server/api/v1/auth - login.post.ts
export default defineEventHandler(async (event) => {
    console.log('this is auth:login!')
});

I've tried to handle CORS in the following ways:
middleware Method 1

export default defineEventHandler((event) => {
    handleCors(event, {
        methods: ['GET', 'POST', 'PATCH', 'DELETE', 'OPTIONS'],
        allowHeaders: '*',
        origin: 'http://localhost:3000',
        credentials: true
    }
});

middleware Method 2, from: https://www.reddit.com/r/Nuxt/comments/109au1x/how_so_enable_cors_in_nitro/

export default defineEventHandler((event) => {
    setResponseHeaders(event, {
        'Access-Control-Allow-Methods': 'GET,HEAD,PATCH,POST,DELETE',
        'Access-Control-Allow-Origin': 'http://localhost:3000',
        'Access-Control-Allow-Credentials': true
    });
    if(event.method === 'OPTIONS') {
        event.node.res.statusCode = 204;
        event.node.res.statusMessage = "No Content.";
        return 'OK';
    }
});

nuxt.config.ts Method: routeRules and nitro: routeRules

export default defineNuxtConfig({
   // also tried with variation - nitro: { routeRules: {...}}
    routeRules: {
        'api/v1/**': {
            cors: true,
            headers: {
                'access-control-allow-methods': 'GET,HEAD,PATCH,POST,DELETE',
                'access-control-allow-origin': 'http://localhost:3000',
                'access-control-allow-credentials': 'true'
            }
        }
    }
});

nuxt.config.ts Method: nuxt-security https://nuxt-security.vercel.app/getting-started/setup

export default defineNuxtConfig({
    modules: ['nuxt-security'],
    routeRules: {
        '/api/v1/**': {
            security: {
                corsHandler: {
                    origin: 'http://localhost:3000',
                    methods: '*',
                    credentials: true
                }
            }
        }
    }
});

For reproduction steps I've setup the following:
https://stackblitz.com/edit/github-wovvta

If anyone has any ideas with regards to this it would really be much appreciated, thanks!

@Hebilicious Hebilicious changed the title CORS issue CORS issue with non GET methods Oct 9, 2023
@Hebilicious Hebilicious changed the title CORS issue with non GET methods CORS is not working with non GET methods Oct 9, 2023
@Hebilicious Hebilicious added bug Something isn't working nuxt reproduction labels Oct 9, 2023
@genu
Copy link
Contributor

genu commented Oct 10, 2023

I'm facing this as well, spend a day trying to figure out why I just can't get CORS to work.

I have no idea why there are so many ways that seem to do the same thing:

handleCors()
appendCorsHeaders()
appendCorsPreflightHeaders()

and of course, the cors configuration that can be set in nuxt.config.ts

I also noticed inconsistent behavor if you use any of the above methods in the handler itself, or a middleware.

If anyone has a workaround to at the very least be able to just disable CORS globally, until this is fixed.

@Ibz786
Copy link
Author

Ibz786 commented Oct 12, 2023

I created a build of my nuxt / nitro project on Render
When I targeted a POST method it worked, so I'm wondering if the CORS / preflight issue only in when in localhost?

Another thing I tried I tried and noticed was, I created the following two:

A minimalistic Vue SSR app using Vike

{
  "name": "vike-app",
  "version": "1.0.0",
  "description": "",
  "private": true,
  "type": "module",
  "scripts": {
    "dev": "npm run server:dev",
    "prod": "npm run build && npm run server:prod",
    "build": "vite build",
    "server:dev": "node ./server",
    "server:prod": "cross-env NODE_ENV=production node ./server"
  },

A basic, bare bones Express server

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "private": true,
  "type": "module",
  "scripts": {
    "start": "node index.js",
    "dev": "nodemon index.js"
  },
  ...
}

It's important to note, that Vike uses Vite whilst my bare bones Express server doesn't
With both implementations I added in the cors library with the following config:

const ALLOWED_ORIGINS = ['http://localhost:3000', 'http://localhost:5000']

app.use(cors({
    origin (origin, callback) {
        if(!origin) return callback(null, true); // allow requests with no origin - (like mobile apps or curl requests)

        if (!ALLOWED_ORIGINS.includes(origin)) {
            const msg = 'The CORS policy for this site does not allow access from the specified Origin.'
            return callback(new Error(msg), false);
        }
        return callback(null, true);
    },
    credentials: true
}));

With the Express.js server, as per my config, all HTTP Methods including 'GET', 'PATCH', 'POST', 'PUT', 'DELETE', worked find with CORS correctly
However, with the Vike, GET worked fine, but then using POST for example didn't work

I'm just wondering if the common factor of CORS issues with Nuxt / Nitro, Vike is linked to Vite or its configuration, since Express worked fine?

Thoughts on this?

@nethriis
Copy link

nethriis commented Dec 3, 2023

Same issue, do you have a solution ?

@Mateleo
Copy link

Mateleo commented Dec 5, 2023

Same issue here with POST

@MarkusWendorf
Copy link

I suspect that this is an issue with preflight requests not being handled correctly.

@Ibz786 can you provide a Github Repo with both the server implementation and the client code that is calling the API. The sandbox provided only includes the server part if I'm not mistaken.

@gkTim
Copy link

gkTim commented May 1, 2024

Anyone found a solution? Also have this issue.
Maybe it would be great a add a guide to the documentation on how to handle CORS correctly.

@TheAlexLichter
Copy link
Member

Closing in favor of unjs/h3#744, a PR is already submitted for it 👍🏻

@TheAlexLichter TheAlexLichter closed this as not planned Won't fix, can't repro, duplicate, stale May 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working cors nuxt reproduction
Projects
None yet
Development

No branches or pull requests

8 participants