CORS issue while sending request to Node Server using Axios - reactjs

I am stumbled upon a problem, perhaps some one can help. Currently i have installed axios via npm in react project and while sending a request to node backend i am getting the following error
Access to XMLHttpRequest at 'http://mechanicapp.test:3333/api/manufacturer?pagination=true&perPage=3' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header contains the invalid value 'false'.
I have read earlier stack overflow post on this concern but none of them solve my problem.
i have tried to set Access-Control-Allow-Origin in the header of request but it did not help.
w.Header().Set("Access-Control-Allow-Origin", "*")
I am using Adonis.js Framework for my backend, I am wondering if some on can help me out.
My code for sending request is as follows,perhaps it can help you in solving the query.
function checkAuthTokenExclusion(arr, url) {
return (arr.indexOf(url) != -1);
}
let responseFormat = {
error: false,
response: {},
}
/*exclusion array, add those url to this array for which you dont want to set token in header*/
var exclusion = ['user-login'];
const axiosRequest = () => {
const defaultOptions = {
baseURL: "http://mechanicapp.test:3333/api/",
/* method: 'get',*/
headers: {
'Content-Type': 'application/json',
},
};
// Create instance
let instance = axios.create(defaultOptions);
// Set the AUTH token for any request
instance.interceptors.request.use(function (config) {
/*the token will be added to header for those url which are not found in the exclusion array*/
if (!checkAuthTokenExclusion(exclusion, config.url)) {
const token = localStorage.getItem('fixlo-access-token');
config.headers.Authorization = token ? `Bearer ${token}` : '';
}
return config;
});
return instance;
};
async function makeRequest(requestType = 'get', url, data = {},optionalConfig = {}) {
let requestObj = null;
switch (requestType) {
case 'get':
/*sample params pass code for get requests*/
/*
axiosRequest().get('/', {
params: {
results: 1,
inc: 'name,email,picture'
}
});*/
requestObj = axiosRequest().get(url, data);
break;
case 'post':
requestObj = axiosRequest().post(url, data,optionalConfig);
break;
case 'put':
requestObj = axiosRequest().put(url, data,optionalConfig);
break;
case 'delete':
requestObj = axiosRequest().delete(url, data);
break;
default:
/*if no params matches in switch case*/
requestObj = axiosRequest().get(url, data);
}
await requestObj.then(callResponse => {
/*success*/
responseFormat.response = callResponse.data;
}).catch(error => {
/*error*/
responseFormat.error = true;
responseFormat.response = error.response.data;
});
return responseFormat;
}
// export default axiosRequest();
export default makeRequest;```

Cross-Origin Resource Sharing (CORS) is a way to allow incoming HTTP requests from different domains.
It is very common in AJAX applications where the browser blocks all cross-domain requests if the server does not authorize them.
So to solve your query, your server should enable the cross origin requests, not the client.
Adonis.js give built in feature to turn the CORS on and off,turning it on will let your server start accepting requests from cross origins.
To do so, simply in your adonis server directory
Go to your config directory.
Find cors.js and change origin from false to true
Your server should know start accepting request from cross origins.
You can read more here at https://adonisjs.com/docs/4.1/cors

Related

sveltekit TypeError: immutable

I'm using sveltekit 1.0.0-next.483 running with npm run dev -- --host
connecting to an endpoint with a mobile device i get this error:
typeError: immutable
at Headers.append ([..]node_modules/undici/lib/fetch/headers.js:227:13)
This error only occurs on mobile device, connecting to the local net ip address.
my endpoint: src/routes/gqlendpoint/+server.ts
const base = 'http://localhost:4000/graphql';
export async function POST( opts: { request: Request} ): Promise<Response> {
const { request } = opts;
const body = await request.json();
const response = await fetch(base, {
//credentials:"include",
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body)
});
return response;
}
the only way I found to unlock this situation, is by commenting a line of code inside node_modules/undici/lib/fetch/headers.js
// 3. If headers’s guard is "immutable", then throw a TypeError.
// 4. Otherwise, if headers’s guard is "request" and name is a
// forbidden header name, return.
// Note: undici does not implement forbidden header names
if (this[kGuard] === 'immutable') {
**//throw new TypeError('immutable')**
} else if (this[kGuard] === 'request-no-cors') {
// 5. Otherwise, if headers’s guard is "request-no-cors":
// TODO
}
which is certainly not a good solution.
You have to return new Response body to avoid this issue , see example code below.
return new Response('test example')
in place of return response;

How to fix python flask cors issue using flask-cors library

I could really use some help. I can't figure out what I'm doing wrong. I keep getting
Edit : Frontend React application runs on localhost:3000, backend is running on localhost:5000
Access to XMLHttpRequest at 'http://localhost:5000/api/auth/login' 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.
def create_app(test_config=None):
logger = logging.getLogger(__name__)
logger.info("Flask App Starting")
# create and configure the app
app = Flask(__name__, instance_relative_config=True)
CORS(app)
cors = CORS(app, resources={r"/api/*": {"origins": "*"}})
logging.getLogger('flask_cors').level = logging.DEBUG
app.config.from_mapping(
SECRET_KEY="dev",
JWT_SECRET_KEY="super secret key",
JWT_ACCESS_TOKEN_EXPIRES=timedelta(hours=2),
)
if test_config is None:
# load the instance config, if it exists, when not testing
app.config.from_pyfile("config.py", silent=True)
else:
# load the test config if passed in
app.config.from_mapping(test_config)
jwt = JWTManager(app)
"""
Adding blueprints
"""
from app.routes import tester
from app.routes import auth
from app.routes import api_routes
from app.routes import similar_routes
app.register_blueprint(tester.bp)
app.register_blueprint(auth.bp)
app.register_blueprint(api_routes.bp)
app.register_blueprint(similar_routes.bp)
#app.before_request
def check_login():
"""Before each request check if token exist."""
pass
logger.info("Checking if token is required")
if (not getattr(app.view_functions[flask.request.endpoint], "is_public", False)):
logger.info("Token required")
try:
result = verify_jwt_in_request(locations="headers")
logger.debug(f"Identity sent in is {get_jwt_identity()}")
except Exception as e:
logger.error("Error occured during checking token")
logger.error(e)
return jsonify(msg="Token Expired"),401
#app.errorhandler(Exception)
def all_exception_handler(error):
logger.error("Error caught" + str(error) )
return jsonify(msg="Oh no! A Server error occured. :,( "), 500
return app
if __name__ == "__main__":
loggingSetup()
app = create_app()
logger.info("App Created")
app.run(debug=True)
logger.info("App Running")
I'm making API calls from my react frontend, using axios
axios.defaults.baseURL = "http://localhost:5000/api"
function getHeaders(token){
return {
'Accept': 'application/json',
'Content-Type': 'application/json;charset=UTF-8',
"Authorization": "Bearer " + token,
'Access-Control-Allow-Origin': '*'
}
}
async function createCustomObject(token) {
let url = "/ontology/create-object";
let options = {
method: "POST",
url: url,
headers: getHeaders(token),
};
let response = await axios(options).then((response) => {
let data = response.data
}).catch((error) => {
handleError(error.response)
})
return response;
What am I missing?
You would set your origin to http://localhost:3000:
cors = CORS(app, resources={r"/api": {"origins": "http://localhost:3000"}})
'Access-Control-Allow-Origin': 'http://localhost:3000'
I resolved my issue using proxy after trying a couple of failed attempts using CORS solution.
I simply put "proxy": "http://127.0.0.1:5000" in my package.json and therefore, I can then use
fetch(`/test`)
.then((res) => res.json())
.then((data) => {
//do something
});
easily in my app without actually providing the full url to the backend (http://127.0.0.1:5000).

InvalidSignatureException from POST request

I have a Lambda function that handles reading data from a file(stored inside S3 bucket) as well as inserting data to a Dynamodb table. This Lambda function is exposed as a REST endpoint using API gateway. The function accepts GET request as well as POST request. I'm making GET/POST requests from my REACT project using axios and aws4(for signing) libraries. GET request is to read data from a file stored inside S3 and it works just fine. And POST request is for inserting data into Dynamodb table. However, it doesn't work and AWS returns InvalidSignatureException error as a respond. This is an excerpt of my code :
createAWSSignedRequest(postData) {
let request = {};
if (postData) {
request = {
host: process.env.AWS_HOST,
method: 'POST',
url: process.env.AWS_URL,
path: process.env.AWS_PATH,
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(postData)
}
} else {
request = {
host: process.env.AWS_HOST,
method: 'GET',
url: process.env.AWS_URL,
path: process.env.AWS_PATH
}
}
let signedRequest = aws4.sign(request, {
secretAccessKey: process.env.AWS_SECRET_KEY,
accessKeyId: process.env.AWS_ACCESS_KEY
});
return signedRequest;
}
This is how GET request is made :
let signedRequest = this.createAWSSignedRequest('GET');
axios(signedRequest)
.then(response => {
})
.catch((error) => {
console.log("error",error);
});
This is how POST request is made :
const data = {
uuid: "916b7d90-0137-11e8-94e6-116965754e23", //just a mock value
date : "22/jan/2018",
user_response: [
{
question:"this is quesiton1",
choice:"user selected A"
},
{
question:"this is quesiton2",
choice: "user selected b"
},
{
question:"this is quesiton3",
choice: "user selected C"
}
]
};
let signedRequest = this.createAWSSignedRequest(data);
axios(signedRequest)
.then(response => {
......
})
.catch((error) => {
console.log("error",error);
});
As you can see, the code for both GET and POST requests are exactly the same (except payload and method type). I'm singing with the same secret access key and access key id for both requests. I'm not sure why one request results in "InvalidSignatureException" when the other doesn't. Can anyone shed a light on this issue for me.
Thanks
After having discussion with AWS4 lib developer, I figured out what I did wrong. AWS4 uses "body" as a payload attribute to compute signature. However, Axios uses "data" attribute as payload. My mistake was only setting either one of them. So when I set just "data" attribute, the payload was present in the request and content-length is computed correctly. However, the signature was incorrect since the payload was not taken into consideration when computing signature. When I set just "body", payload was not present in the request because Axios does not use "body" attribute for payload. The solution is to set both attributes with payload. I hope this helps to anyone who are having the same issue I have.
If you use the AWS Amplify library it has a module called API which should fit your use cases, and it will perform Sigv4 signing for you either with authenticated or unauthenticated roles. The Auth category uses Cognito as the default implementation. For instance:
npm install aws-amplify --save
Then import and configure the lib:
import Amplify, { API } from 'aws-amplify';
Amplify.configure({
Auth: {
identityPoolId: 'XX-XXXX-X:XXXXXXXX-XXXX-1234-abcd-1234567890ab',
region: 'XX-XXXX-X'
},
API: {
endpoints: [
{
name: "APIName",
endpoint: "https://invokeURI.amazonaws.com"
}
]
}
});
Then for your API Gateway endpoint calling a Lambda:
let apiName = 'MyApiName';
let path = '/path';
let options = {
headers: {...} // OPTIONAL
}
API.get(apiName, path, options).then(response => {
// Add your code here
});
More info here: https://github.com/aws/aws-amplify

React Axios Cheerio parsing of GitHub response

I'm attempting to make a request from Axios to retrieve data from GitHub. I am receiving a failure error that makes sense, and I'm wondering if this is the expected behavior and this type is simply not possible from the client side, or if there is a way to make this request that I am simply missing:
componentDidMount() {
axios
.get('https://github.com/users/lukeschlangen/contributions',{
headers: {
'Access-Control-Allow-Origin': '*'
}
})
.then(res => {
this.streakCounter(res);
})
.catch(err => console.log(err));
}
streakCounter(body) {
const $ = cheerio.load(body);
var data = [];
$('svg').find('rect').each(function(index, element) {
data.push({
count: parseInt($(element).attr('data-count')),
date: new Date($(element).attr('data-date'))
})
});
var yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
data = data.sort(function(a, b) {
return new Date(b.date) - new Date(a.date);
}).filter(function(el) {
return el.date.getTime() <= yesterday.getTime();
});
var streakCount = 0;
for (var i = 0; i < data.length; i++) {
if (data[i].count == 0) {
break;
}
streakCount++
}
console.log('streakCount:', streakCount);
}
My guess is that this is something GitHub might simply reject outright and that there is no way around this from the client side. This is the error I get in response:
Failed to load https://github.com/users/lukeschlangen/contributions:
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. The response had HTTP status code 404.
I'd prefer to do this without a server if possible, so I want to make sure before I throw in the towel.
You won't be able to get around this in the front-end because it requires server-side changes by Github.
But, you could have your front-end ping your back-end, which then hits that URL and passes the information forward, or use a service to get around this like cors-anywhere.

How to set common request headers for every ajax request in ext5?

I have to set customized headers for every ajax request, is there a way to do this only once without having to config it manually in every ajax proxy.
proxy: {
headers: {
token: 'xyz' // this token that every proxy should contain to communicate with our remote server.
}
}
In jQuery i can accomplish this by using "ajaxPrefilter" like following:
jQuery.ajaxPrefilter(function(options, originalOptions, jqXHR) {
jqXHR.setRequestHeader('token', 'xyz');
}
But i don't known how to do it properly in extjs, please help!
Ext.Ajax.setDefaultHeaders({
'Accept':'application/json'
});
how about overriding Ext.data.proxy.Ajax like this
Ext.override(Ext.data.proxy.Ajax, {
headers: {
token: 'xyz' // this token that every proxy should contain to communicate with your remote server.
}
});
Ext.Ajax is a singleton, so you should be able to do this:
Ext.Ajax.defaultHeaders = {
token: 'xyz'
};
Place it at the beginning of your app, or where you see fit, and then each subsequent Ajax request will have this token.
Below code adds CSRF header and token to every ajax request made. Note beforerequest
Ext.Ajax.on('beforerequest', function(conn, options) {
var x = document.getElementsByTagName("META");
var token = "";
var headerVal = "";
var i;
for (i = 0; i < x.length; i++) {
if (x[i].name == "_csrf")
{
token = x[i].content;
}else if (x[i].name=="_csrf_header"){
headerVal = x[i].content;
}
}
//Ext.Ajax.defaultHeaders = Ext.apply(Ext.Ajax.defaultHeaders || {}, { headerVal : token });
Ext.Ajax.setDefaultHeaders({
headerVal : token
});
});

Resources