I've been trying to set up CORS in Sails 0.12.0 on a per route basis. According to the documentation, it should only be a matter of adding a "cors" object to the routes where you want to override the global settings. I did it like this:
routes.js
module.exports.routes = {
'/': {
view: 'homepage'
},
'GET /widget/render/:id': {
controller: 'WidgetController',
action: 'render',
cors: {
origin: '*',
credentials: false
}
}
};
I'm not sure if the headers should be added inside the controller, or if it's enough to use the route configuration, but I'm only getting empty CORS headers in every request.
Related
I have CORS globally configured like this, to handle credentials:
app.use(cors({ origin: 'https://example.com', credentials: true }))
But on certain routes, I need to allow options requests, so following the documentation, I'm doing something like this:
router.options('/someroute', cors())
router.get('/someroute', cors(), someOtherMiddleware, async (req, res) => {
// do stuff
}
My global CORS policy seems to override the route policy, but only on the options method, I think. I'm trying to come up with a way to make both of these CORS policies play nicely. I have also tried the following, but this doesn't work either. Whichever one I put first seems to override the other one.
app.options('*', cors())
app.use(cors({ origin: 'https://example.com', credentials: true }))
The reason my 2nd code snippet above wasn't working as expected was because I needed to add the preflightContinue property when setting the cors policy at the app level. Otherwise it will ignore cors policies on options routes set at the route level. Kind of a poorly documented thing.
The final solution was to do this at the app level:
app.use(cors({
origin: 'https://example.com',
credentials: true,
preflightContinue: true,
}))
Now this cors policy on the options route actually works:
router.options('/someroute', cors())
router.get('/someroute', cors(), someOtherMiddleware, async (req, res) => {
// do stuff
}
Ugh, spent so long figuring this one out. Hope this saves someone some time.
I am trying to configure a proxy for my API requests using http-proxy-middleware, which the create react app docs suggest. I set up my proxy like this, in the setupProxy.js file:
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function (app) {
app.use(
createProxyMiddleware("/post", {
target: 'https://postman-echo.com',
changeOrigin: true,
logLevel: 'debug'
})
);
};
then, I do a simple POST to an endpoint:
const response = await fetch("/post", {
method: 'POST',
headers: {
'content-type': 'application/json;charset=UTF-8'
},
body: JSON.stringify({ foo1: "bar1", foo2: "bar2" })
});
console.log(await response.json());
According to the http-proxy-middleware docs, I should expect a proxy that does something like this:
[HPM] POST /post -> https://postman-echo.com/post
But instead, the debugger shows this:
[HPM] POST /post -> https://postman-echo.com
The path, /post, does not get appended to the proxy request. The target should actually be https://postman-echo.com/post. My client gets a 404 error because https://postman-echo.com on its own does not match anything on the backend.
If it did reroute correctly, I should expect the same results as a CURL request
curl -X POST -F 'foo1=bar1' -F 'foo2=bar2' https://postman-echo.com/post
{"args":{},"data":{},"files":{},"form":{"foo1":"bar1","foo2":"bar2"},"headers":{"x-forwarded-proto":"https","x-forwarded-port":"443","host":"postman-echo.com","x-amzn-trace-id":"Root=1-61200c54-7b5809be3e78040f09edcd42","content-length":"240","user-agent":"curl/7.64.1","accept":"*/*","content-type":"multipart/form-data; boundary=------------------------bb54b419e41f4a4a"},"json":null,"url":"https://postman-echo.com/post"}%
But I 404 because the path is not added. Why is the path being left out?
I created a simple app that recreates my issue. This looks similar to this issue but they are not the same (I am using the same syntax as the answer suggests).
I got it working. The problem was that I was testing with an endpoint that 404'd. I got confused because the debugger doesn't append /post to the end of the log like the docs say it should.
I have a React app which is running webpackdevserver on port 3000.
I have an AWS .NetCore Lambda server running localhost on port 5050.
When I try and make a request I am getting the cors error:
Access to fetch at 'http://localhost:5050/' from origin
'http://localhost:3000' has been blocked by CORS policy: Response to
preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. If an opaque response serves your needs, set the request's
mode to 'no-cors' to fetch the resource with CORS disabled.
I was hoping to use a proxy, as per the documtation here in order to forward my requests on using the same domain to get round this.
https://medium.com/#drgenejones/proxying-an-external-api-with-webpack-serve-code-and-a-restful-data-from-separate-endpoints-4da9b8daf430
However it is not working, I don't see any difference at all with the settings applied, can anyone help?
devServer: {
port: 3000,
disableHostCheck: true,
compress: true,
host: 'localhost',
proxy: {
'/': {
target: 'http://localhost:5050',
secure: false,
},
},
},
My JavaScript to call the server is like this... I have also tried with the url http://localhost:3000 but this just returns a bad request error.
const result = await fetch('http://localhost:5050', {
method: 'POST',
headers: new Headers({ 'Access-Control-Allow-Origin': '*' }),
body: JSON.stringify({
method: 'upload',
test: 'test',
}),
});
I guess the issue is to set / which could just fetch the current server so you might need to differentiate between your web app vs your server (most likely via a specific path such as /api, but you can choose to pass this path to your proxy server or not).
So you would change as following:
Your configuration of proxy first to take api to go through proxy:
proxy: {
'/api': {
target: 'http://localhost:5050',
pathRewrite: {'^/api' : ''}, // In this case we don't pass `api` path
}
}
Next thing is to change your code to call the same domain + port 3000 normally (proxy would do the rest for you by passing to your server with port 5050 which you configured):
const result = await fetch('http://localhost:3000/api', {
// ...
});
I am writing BE application using Node JS and Hapi (v17). While the server is running and I try to call an endpoint using POST method I keep receiving an error message:
Failed to load http://localhost:8001/login: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.
I wanted to enable CORS on the server site, but nothing works for me.
here is how I enable CORS on the server site:
const hapi = require('hapi')
const server = hapi.server({
port: 8001,
host: 'localhost',
routes: {
cors: true
}
})
I was also trying to enable cors for the specific route but this also has no effect:
server.route({
method: 'POST',
path: '/login',
config: {
cors: {
origin: ['*'],
additionalHeaders: ['cache-control', 'x-requested-with']
}
},
handler: async (request, reply) => {
return User.login(request, reply)
}
})
Does anyone know what should I do to enable CORS and get rid of the problem?
Additionally, there is a screenshot from the browser's network tab:
EDIT:
I have added route that handles OPTIONS method and now I have another issue.
Failed to load http://localhost:8001/login: Request header field access-control-allow-credentials is not allowed by Access-Control-Allow-Headers in preflight response.
And here is how things look like in the network tab:
cors: {
origin: [
'*'
],
headers: ["Access-Control-Allow-Headers", "Access-Control-Allow-Origin","Accept", "Authorization", "Content-Type", "If-None-Match", "Accept-language"],
additionalHeaders: ["Access-Control-Allow-Headers: Origin, Content-Type, x-ms-request-id , Authorization"],
credentials: true
}
You should also probably define a qualified domain, instead of just * wildcard
Put together the below.
server.route([
{
method: "POST",
path: "/authorize",
config: {
auth: false,
cors: {
origin: ['*']
}
},
handler: (request, reply) => {
...
reply.redirect(redirectUrl)
}
}
])
I want to use with client-side JavaScript browser fetch API. The cors part is necessary to avoid using the no-cors mode for fetch and to get a non-opaque response.
If I use only 'authin the config section or onlycors` they work fine, but together hapi complaints that the configuration is wrong.
Why is that?
inside config object you cannot use key cors. for correct configuration you have to put cors key inside this like this
server.connection({
port: dbConfig.port,
routes: { cors: true } // set cross origin by hapi inbuilt property
// tls: tls
})