how to send HTTP request with APIKEY - fetch

I have an API Gateway created to trigger my lambda function. I am trying to secure the invoke URL. I understand that we can use the Lambda Authorizer or the APIKEY. I am trying to use the API key but not sure how to pass the API key using fetch.
I have also linked the API to the API Keys and the usage Plans.
I am trying to access the URL from the client-side.
invokeurl is referring to my Invoke URL which will return the JSON object.
egkeyname is my key value which I am not able to share.
Client.py:
onMount(async () => {
const res = await fetch('invokeurl',{
method:'get',
headers: new Headers ({
'Access-Control-Allow-Origin' : '*',
'Access-Control-Allow-Methods':'OPTIONS,POST,GET',
'X-API-KEY' :'egkeyname'
})
}); //wait until the promise return result
data = await res.json();
});
But I get an error:
Access to fetch at '..invoke ur...' 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.
Uncaught (in promise) TypeError: Failed to fetch
GET https:invokeurl net::ERR_FAILED
My lambda function:
responseObject = {}
responseObject['statusCode'] = 200
responseObject['headers']={}
responseObject['headers']['Content-Type'] = 'application/json'
responseObject['headers']['Access-Control-Allow-Origin'] = '*'
responseObject['headers']['Access-Control-Allow-Methods'] = 'OPTIONS,POST,GET'
return responseObject
How do I access the URL with the APIkey?

Solved it on my own. I was using the wrong information in the Header.
It should be:
onMount(async () => {
const res = await fetch('invokeurl',{
method:'get',
headers: new Headers ({
'Access-Control-Request-Headers': 'Origin, X-Requested-With, Content-Type, Accept, Authorization',
'Origin' : '*',
'Access-Control-Request-Method':'OPTIONS,POST,GET',
'X-API-KEY' :'egkeyname'
})
}); //wait until the promise return result
data = await res.json();
});

Related

Google Firebase Messaging API facing CORS error

Hi there Guys i'm tryng to subscribe Firebase Cloud Messaging channels with provided token via capacitor/ioni app using PWA. But i got a CORS issue when i publish the www folder, instead on localhost it is working
This is the code im using in .ts file
this.devices = response;
FirebaseMessaging.requestPermissions().then(result => {
if(result.receive === 'granted')
{
FirebaseMessaging.getToken(
{
vapidKey: 'my-vapid-key',
}
).then( result => {
const token = result.token;
this.devices.forEach(i => {
let topic = i.serial
fetch('https://iid.googleapis.com/iid/v1/'+ token +'/rel/topics/'+ topic, {
method: 'POST',
headers: new Headers({
'Access-Control-Allow-Origin': '*',
"Access-Control-Allow-Methods": "DELETE, POST, GET, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization, X-Requested-With",
'Authorization': 'key=my-key'
})
}).then(response => {
alert('Fatto')
if (response.status < 200 || response.status >= 400) {
throw 'Error subscribing to topic: '+response.status + ' - ' + response.text();
}
console.log('Subscribed to "'+topic+'"');
}).catch(error => {
console.error(error);
})
})
this.addReceivedListener();
the error i faced is: "https://iid.googleapis.com/iid/v1/xxxxxxxxtokeeeen/rel/topics/mytopic' from origin 'https://mysite.site.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."
there is no CORS on the other side, so we need to disable it and its working

NgRok not reading method

node js, and ngRock, it seems that ng rock is not receiving the GET method every time i make a GET request the method deployed in ngrok is OPTIONS /category, instead of GET / category.
picture
and im not getting any response from the server
react fetch
try {
const response = await fetch(global.config.Node_API + 'categorias', {
method: 'GET'
});
if (!response.ok) {
throw new Error(`Error!, Fallo en la coneccion`);
}
const result = await response.json();
this.setState({cont:1,categor: result});
} catch (err) {
console.log(err.message);
}
in the console im getting error
Access to fetch at 'https://5833-45-229-42-135.ngrok.io/categorias' from origin 'http://localhost:3001' has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.
in nodeJs im using
app.use(cors())

Firebase HTTP Function triggered twice when POST request sent with headers

I deployed a firebase HTTP cloud function and am experiencing this (unexpected) behavior:
when I call the function (using POST) from a browser environment with fetch(), the function gets triggered twice, one time without any data sent in the body, and another time as I would expect it. In the frontend (chrome network tab) I can only see 1 request, the successfull one.
this does only happen with POST requests
this does only happen when the request is sending headers
Is this normal behavior that I dont understand or a potential bug?
my minimal cloud function
exports.run = functions.https.onRequest(async (req, res) => {
// ALLOW CORS FOR POST REQUEST:
// => https://stackoverflow.com/a/38259193
res.set('Access-Control-Allow-Origin', '*');
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
return res.status(200).send({
status: "ok",
body: req.body,
query: req.query,
}).end();
});
calling from frontend
// example data (not a real one)
const url = "https://us-central1-myproject.cloudfunctions.net/test";
const postData = { x: 1, y: 2 };
// GET request => ✅ works as expected
fetch(url);
// POST request without headers => ✅ works as expected
fetch(url, {
method: 'POST',
body: JSON.stringify(postData),
});
// POST request with headers => ❌ 2 requests get triggered
fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(postData),
});
This behavior is happening because of the CORS preflight request:
A CORS preflight request is a CORS request that checks to see if the CORS protocol is understood and a server is aware using specific methods and headers.
...
A preflight request is automatically issued by a browser, and in normal cases, front-end developers don't need to craft such requests themselves. It appears when a request is qualified as "to be preflighted" and omitted for simple requests.
As pointed in this other question:
As long as you’re adding a Content-Type': 'application/json' header to the request, the browser is going to automatically on its own do a CORS preflight OPTIONS request before trying the request from your code.
Therefore, this is a normal behavior and is not a problem of Cloud Functions for Firebase.
In order to not have the two requests, you can change the header request as suggested by this answer:
// example data (not a real one)
const url = "https://us-central1-myproject.cloudfunctions.net/test";
const postData = { x: 1, y: 2 };
// POST request with different header => ✅ only one request is triggered
fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: JSON.stringify(postData),
}).then(data => console.log(data));

Can't do a post request using axios, returning unauthorised 401 error

I created an auth service from scratch using Redux, React and Node. Everything was working fine until I wire up my Post section o redux to my BackEnd. The redux part is ok I guess. My problem is when I send the Authorization Bearer token. I'm being able to post using insomnia. But when I try to post using the web app I can't.
This is my action:
export const createPost = ( formValues: any) => async(dispatch: any, getState: any) => {
const { userId } = getState().auth;
let token = userId
const headers = {
header: {
'Content-Type' : 'application/json',
'Accept' : 'application/json',
Authorization: `Bearer ${token}`
}
};
const response = await AlleSys.post('/posts', {...formValues, headers})
// dispatch({type: CREATE_POST, payload: response.data})
userId is my JWT token.
I already set up Cors on my backend
const corsOptions ={
origin:'http://localhost:3000',
credentials:true, //access-control-allow-credentials:true
optionSuccessStatus:200
}
app.use(cors(corsOptions))
On Insomnia. The same request on insomnia works fine.
On insomnia I'm using the same bearer token from my application, so the problem is not the JWT.
Querying an endpoint with GET, POST, PUT, DELETE from a Nodejs server or Insomnia will result in calling before checking the OPTIONS.
But browsers will limit the HTTP requests to be at the same domain which makes you run into CORS issues. Since Insomnia is not a browser and CORS is a browser security restriction only, it didn't get limited.
From docs for the CORS you are using:
Certain CORS requests are considered 'complex' and require an initial OPTIONS request (called the "pre-flight request"). An example of a 'complex' CORS request is one that uses an HTTP verb other than GET/HEAD/POST (such as DELETE) or that uses custom headers. To enable pre-flighting, you must add a new OPTIONS handler for the route you want to support:
So I think you should include app.options('*', cors()) before all routes and put it at the top of your file to be processed first.
I changed my code to:
export const createPost = ( formValues: any) => async(dispatch: any, getState: any) => {
const { userId } = getState().auth;
let token = userId
const headers = {
authorization: `Bearer ${token}`
};
const response = await AlleSys.post('/posts', {...formValues}, {headers})
And Worked!

app.post on parse heroku server is unauthorized

I am trying to post to my server from twilio, but I am getting a 403 error. Basically my parse-heroku serve is rejecting any request from twilio. I am working with TWIMLAPP and masked numbers. I am having trouble posting to a function in my index file when a text goes through. In my TWIMLAPP my message url is https://parseserver.herokuapp.com/parse/index/sms Any help is appreciated. These are the errors in twilio
var app = express();
app.use(require('body-parser').urlencoded());
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'https://www.twilio.com');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
res.setHeader("X-Parse-Master-Key", "xxxxxxx");
res.setHeader("X-Parse-Application-Id", "xxxxxx");
// Pass to next layer of middleware
next();
});
app.post('/sms', twilio.webhook({ validate: false }), function (req, res) {
console.log("use-sms")
from = req.body.From;
to = req.body.To;
body = req.body.Body;
gatherOutgoingNumber(from, to)
.then(function (outgoingPhoneNumber) {
var twiml = new twilio.TwimlResponse();
twiml.message(body, { to: outgoingPhoneNumber });
res.type('text/xml');
res.send(twiml.toString());
});
});

Resources