Hapi.js with Glue CORS headers not setting - node.js

Okay, so this is what my glue manifest looks like. As you can see the cors object is being set but I keep getting this stupid error when running from frontend app: localhost:3000.
Access to XMLHttpRequest at 'http://localhost:8082/api/v1/check_out_order' 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.
"glueManifest": {
"server": {
"port": 8082,
"routes": {
"cors": {
"origin": ["*"],
"additionalHeaders": ["cache-control", "x-requested-with"]
}
}
},
anyone that may have a solution for me will be appreciated much! TIA!

try this: var server= new Hapi.Server({ port: 8082, routes: { cors: true }});

Your back-end needs to accept also the 'OPTION' type of HTTP request on all endpoints + add the header to all your responses.
The HTTP OPTIONS method is used to describe the communication options
for the target resource. The client can specify a URL for the OPTIONS
method, or an asterisk (*) to refer to the entire server.
Resource: https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS
The Access-Control-Allow-Origin response header indicates whether the
response can be shared with requesting code from the given origin.
Resource: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin

Related

How to Enable CORS for Credentials and Preflight in Node/Express

I know, there are a billion CORS questions on here. I have gone through dozens. I'm still not sure what the issue is, and I think I understand CORS decently well, but obviously I'm missing something here.
I'm trying to get my (Node/Express) API running on a real URL (i.e. deployed, not using origin: "*"), and tell the browser to actually fulfill requests from my GUI's URL.
For some routes, I need authentication, so I need to add credentials in there.
This is a pretty standard use case, but maybe something changed with the API since I last did this or maybe I just forgot, but regardless I can't seem to get this working and I'm not sure what I'm missing.
There seem to be several ways to go about enabling CORS for all requests in my Express app. I'm currently using the cors middleware with its options object.
Specifically, here's the code I'm using.
const app: express.Application = express();
const corsOptions = {
credentials: true,
origin: 'https://my-gui.example.com',
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',
preflightContinue: true,
}
app.use(cors(corsOptions));
What am I doing wrong? When I make a fetch request from my browser, I receive the below error.
Access to fetch at 'https://my-api.example.com/graphql' from origin 'https://my-gui.example.com'
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.
If I add app.options('*', cors(corsOptions)); before the app.use call (why I would need this when I specified OPTIONS in the method list, I don't know), I get a different error (which leads me to believe I do need this for some reason).
Access to fetch at 'https://my-api.example.com/graphql' from origin 'https://my-gui.example.com'
has been blocked by CORS policy: Response to preflight request doesn't pass access control
check: It does not have HTTP ok status.
I think you are trying to access this website https://my-api.example.com/graphql but the shared snip looks like you gave an access only to https://my-gui.example.com and this is different from above one.
So my answer is please change your snippet like below,
const corsOptions = {
credentials: true,
origin: "*",
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',
preflightContinue: true,
}
(or) try
const corsOptions = {
credentials: true,
origin: ['https://my-gui.example.com','https://my-api.example.com/graphql'],
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',
preflightContinue: true,
}

I am trying to save data in database but facing error

Am creating a react app in which i am using api's for saving data to database but when i post request getting error
let responseData = await fetch('https://********************',
{method: 'post',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(data)});
responseData = responseData.json();```
**error**
Access to fetch at 'https://*********************' from origin
'http://localhost:3000' has been blocked by CORS policy: Request
header field access-control-allow-origin is not
allowed by Access-Control-Allow-Headers in preflight response.
[![enter image description here][1]][1]
[1]: https://i.stack.imgur.com/kMxKF.png
It looks like you need to enable CORS on your server.
I assume from your tags that you are using Express.
You can use the cors npm package:
npm install cors
Then in your app:
const express = require('express')
const cors = require('cors')
const app = express()
app.use(cors())
// The rest of your app
See the docs for more advanced usage:
https://www.npmjs.com/package/cors
I hope this helps solve your problem.
are you trying to fetch directly from https://i.stack.imgur.com? That won't work as you can see in the error. Browsers don't allow making requests to hosts that are not same origin unless explicitly allowed, which in your case is localhost. You would need to run your own server in order to fetch data from other sources. If you are already running a server on localhost you should be fine. But if you are running a server on some other host, you would explicitly need to allow localhost as an exception to CORS policy. Most server frameworks have option to set that. Just google for whatever server you are using :)
You can install Moesif Orign & CORS Changer for chrome and switch to on and it will work for you

HTTPrequest using axios results in CORS error

I build my own API which is running on port 5000. Whenever I want to make a request to it , I get the following error:
Access to XMLHttpRequest at 'http://localhost:5000/user' 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.
I already did some research but the only thing that seems to work is a chrome extension, which isnt ideal.
Here's what i did :
const config = {
headers : {
'Content-Type' : 'application/json',
'Access-Control-Allow-Origin': '*'
}
};
Simply, browsers block responses if server does not allow CORS. So if you are using NodeJS at your API, use this library.

Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Reactjs

I'm deploying my web app to heroku and use the following cors config on the client side.
const instance = axios.default.create({
baseURL: "https://myapp-backend.herokuapp.com",
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
"Access-Control-Allow-Origin": "https://myapp-backend.herokuapp.com"
}
});
And on the server side
const corsConfig = {
origin: ['https://myapp.herokuapp.com', 'http://localhost:3001']
}
app.use(cors(corsConfig));
But I keep getting error: "Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource."
Any help would be much appreciated. Sometimes the config works but sometimes it doesn't...
The custom headers on your request (some of which are misguided) have triggered a pre-flight request for the cross origin request. This means that the browser will separately send an OPTIONS request to your server to ask it if it is OK to process this request before sending the actual request.
You have a couple of choices. First, remove the custom headers that are triggering the pre-flight request. Neither Content-Type or Access-Control-Allow-Origin are appropriate for a request you are sending from the browser. Content-Type belongs to the response and the client does not get to specify anything about what origins are allowed - that's for the server to decide.
If, for some reason, you can't stop the browser from triggering the pre-flight request, then you need to explicitly add support to your server for the OPTIONS pre-flight request. You can see how to use the cors module to do that here.

AWS API Gateway returns access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response

This may seem like it's been asked a million times but I've tried adding to both my frontend (React) and backend (Lambda with Node.js):
Access-Control-Allow-Headers
Access-Control-Request-Headers
Access-Control-Allow-Methods: 'GET,PUT,POST,DELETE,PATCH,OPTIONS'
But I still get this error:
Access to XMLHttpRequest at 'https://<API-INVOKE-URL>/prod/notes' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response.
Here's my Lambda code to handle response:
function buildOutput(statusCode, data) {
let _response = {
statusCode: statusCode,
headers: {
"Access-Control-Allow-Origin": "*"
},
body: JSON.stringify(data)
};
return _response;
};
Here's my React code to send the POST request:
createNote(note) {
return API.post("notes", "/notes", {
headers: {
"Authorization": this.state.token,
"Access-Control-Allow-Origin": "*"
},
body: {
userid: this.state.username,
noteid: 'new',
content: 'from frontend'
}
});
I've tested my Lambda function from the console and it works (able to do CRUD to DynamoDB).
I've turned on CORS for my API Gateway resources and deployed the API.
I've tried using PostMan with:
Headers:Content/Type: application/json
Authorization: <MY_TOKEN>
*With and without* Access-Control-Allow-Origin: *
and it works: the request is sent successfully from PostMan to API Gateway results in a new item in my DynamoDB.
Actually adding some data in header converts POST request to OPTIONS.
So that, it will fire to requests:
1) with OPTIONS method
2) After getting a successfull response for OPTIONS request, the actual API call will occur.
To handle CORS you should use this in the backend.
Just to throw some light to the problem. Some browsers will do a "preflight" check to your endpoint. That means that will invoke your endpoint with OPTIONS method before making the POST method call you expect. In AWS, go to API Gateway and create a new resource , check the option to Create Options, that will create the default response headers that you need to add to your endpoint.
CORS requires a direct connection between the client and server. Your browser may be blocking the connection for security reasons.
HTTP versus HTTPS
I'd also try enabling downloads on your browser.
I believe you should also add the bearer to your token in the authorization header like:
'Bearer TOKEN_VALUE'
Thank you, guys. I've upvoted your answers/suggestions. I'm sure they're helpful in most cases. I've figured out why I had that error.
My bad: I have both resources like this:
/notes/ (method: any)
/notes/{noteid} (method: any)
and the Invoke URL is literally <path>/notes/{noteid} (with the {} included in the string) in AWS API Gateway. I was assuming it'd be something like /notes/:noteid
So the frontend code should be like this:
return API.post("notes", "/notes/{noteid}", {...}

Resources