I'm trying to figure out where to add the "Access-Control-Allow-Origin" header to my create-react-app dev Server config.
So far I'm adding it to config/webpackDevServer.config.js without much luck.
Any idea on where I could add it?
thanks!
Here is a recipe based on #tlfu 's answer for those that are using react-app-rewired. In this case you'll need to define a root level config-overrides.js file containing the following:
module.exports = {
// Extend/override the dev server configuration used by CRA
// See: https://github.com/timarney/react-app-rewired#extended-configuration-options
devServer: function(configFunction) {
return function(proxy, allowedHost) {
// Create the default config by calling configFunction with the proxy/allowedHost parameters
// Default config: https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/config/webpackDevServer.config.js
const config = configFunction(proxy, allowedHost);
// Set loose allow origin header to prevent CORS issues
config.headers = {'Access-Control-Allow-Origin': '*'}
return config;
};
},
};
I hit this problem. In my case, I'm doing something a bit unusual. I'm serving up my React app from a Salesforce Visualforce page, so the page is served from the visual.force.com domain. I've wired up the Visualforce page so that I can run the app locally using Webpack Dev Server and a tunnel (ngrok) to proxy the requests from Salesforce through to localhost. When my app tries to load resources from the apps "public" folder I'd get errors like this:
Failed to load https://xxxx.ngrok.io/scss/bootstrap.scss: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://xxxx.visual.force.com' is therefore not allowed access.
I tried adding devServer: {headers: {'Access-Control-Allow-Origin': '*'}} to the webpack.config.dev.js configuration object, but this didn't work. I found that I had to add the following to the webpackDevServer.config.js file instead: headers: {'Access-Control-Allow-Origin': '*'} (note that "headers" is a top level config property, not nested within the "devServer" property). I read where when you run Webpack Dev Server via the Node API, it doesn't read the devServer config object from your webpack config file.
Apologies if I have the wrong end of the stick, but from your question I'm guessing you're using a backend api with react front end. afaik you don't need cors, just add a proxy to your client/frontend package.json:
"proxy": "http://localhost:5000/"
Dan does say this is only for simple cases, but I hope it helps
Related
I'm using esbuild to develop a SPA and there's a serve function that spins up a dev server, however, if I go to any routes eg "/about", this results in a 404 as because this is a SPA, there is no actual file at that route.
If I could resolve all requests to "/" then that'll fix this issue.
Any ideas?
I just added --single flag to my package, which is a simple wrapper of esbuild --serve. You can check my source code to see how it works.
If the proxy request returns 404, then try again with req.path set to /, that's it.
I have created a React App with the create-react-app cli. Now I use an external library do some requests. (I pass the library my backendUrl and it does the request)
localhost:3000 My ReactJS App (Webpack)
localhost:8081 My Backend Server
Now this leads to an error, saying the Access-Control-Origin-Header was not sent.
SO I looked into how I can activate this with Webpack. What I have done:
Eject Webpack Config to get access to the dev server properties with:
npm run eject
Add following part in the webpack.config.js
devServer: {
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers":
"Origin, X-Requested-With, Content-Type, Accept"
}
}
--> Did nothing
I then tried to use the proxy mechanism:
"proxy": {
"/api": {
"target": "<put ip address>",
"changeOrigin" : true
}
}
But since I use an external Library, which doesn't uses fetch and uses the whole URL to make API calls, this also doesn't work, since from my understanding this only proxies requests like fetch("api/items") for example.
I am a bit confused, since I can't find anything online. Maybe I put the things above in the wrong configuration file or line?
There is also a webpackDevServer.config.js but I can't find anything online about it and as soon as I add something to it, it will produce errors.
CORS needs to be turned on server side, not client side. You can download chrome extensions to bypass CORS but that is for development purposes only.
The reason why you're getting CORS is because you're jumping from 3000 to 8181 which are two different origins. There are multiple different ways to enable CORS depending on what you're using on the backend.
In some cases this is in-fact just a development issues as at runtime, it's all running on the same origin. Most things will give you the ability to proxy calls into the place. For example, here is how .NET SPA Services / Angular 7 do it:
Angular running on :4200
.NET running on :5000
spa.UseProxyToSpaDevelopmentServer("http://localhost:4200");
https://learn.microsoft.com/en-us/aspnet/core/client-side/spa-services?view=aspnetcore-2.2
I am not sure what you're using on the backend, so here is a general article if you're not using .NET
https://enable-cors.org/server.html
I am trying to create a headless drupal app. i am using drupal 8 as a beckend and react as a front-end. i have created REST services in drupal 8 using core rest services module. the problem is when i am calling the api its giving me error i.e
Fetch API cannot load http://192.168.1.246/headless-react/api/events. 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 403. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
I configured the services.yml file for cors.config but still getting error. can anyone have any idea how to solve it ? thanks
Install the CORS module https://www.drupal.org/project/cors
It will allow you to overcome the error related to cross origin
I am using extension for it. The reason why you get this warning because you called api from another domain. Or you you can use nginx.
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
You need to mention what build tools are you using in your front end which uses ReactJS.
Assuming that you are using webpack, you will need to add a proxy in the package.json located at the root directory, like so :
package.json
...
"name": "relay-starter-kit",
"proxy":"<your-base-remote-server-url-here",
"private": true,
...
For instance, if your server is at https://www.myawesomeserver.com, then
"proxy": "https://www.myawesomeserver.com".
In your case, "proxy":"http://192.168.1.246" , should work.
In your application, if you need to access the route, https://www.myawesomeserver.com/home, then you just need to pass the route and webpack will pick up the base url from proxy in package.json
A request for home will look like,
const getHome = async() => {
try{
const raw = await fetch('/home')
const res = await raw.json()
} catch(e) {
console.log(e)
}
}
This is because when you run webpack, it runs the react app on its webpack dev server and for you to communicate with any other server, webpack will have to make a request on your behalf.
If you are not using webpack, this may not be useful for you.
I'm running into an issue with my isomorphic JavaScript app using React and Express.
I am trying to make an HTTP request with axios.get when my component mounts
componentDidMount() {
const url = 'http://ufc-data-api.ufc.com/api/v3/iphone/fighters/title_holders';
axios.get(url).then( res => {
//use res to update current state
})
}
I am getting a status 200 res from the API, but I am not getting any response data and getting an error in my console
XMLHttpRequest cannot load http://ufc-data-api.ufc.com/api/v3/iphone/fighters/title_holders.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:3000' is therefore not allowed access.
However, if I make the request in my server.js
const url = 'http://ufc-data-api.ufc.com/api/v3/iphone/fighters/title_holders';
axios.get(url).then(res => {
//console.log(res);
});
It works fine and I get response data when the server starts. Is this an issue with the actual API or am I doing something wrong? If this was a CORS issue I'm guessing the request in server.js wouldn't work either? Thanks!
CORS is a browser feature. Servers need to opt into CORS to allow browsers to bypass same-origin policy. Your server would not have that same restriction and be able to make requests to any server with a public API. https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
Create an endpoint on your server with CORS enabled that can act as a proxy for your web app.
Fix Without Using External Proxy or Chrome Extension
CORS should be enable in server side! if you can not activate it on server (for example using external API) create a middleware React -> Middleware -> Orginal Server.
Create a Node.js project (Middleware) and use below code in app.js.
const express = require("express");
var cors = require('cors')
const app = express();
app.use(cors());
const { createProxyMiddleware } = require('http-proxy-middleware');
app.use('/api', createProxyMiddleware({
target: 'http://localhost:8080/', //original url
changeOrigin: true,
//secure: false,
onProxyRes: function (proxyRes, req, res) {
proxyRes.headers['Access-Control-Allow-Origin'] = '*';
}
}));
app.listen(5000);
This will pass the request http://localhost:5000/api/xxx to original server (for example http://localhost:8080/api/xxx), and returns the result to client.
Change client (React) to call proxy and get data without CORS error (you only need to change the port in url):
axios.get('http://localhost:5000/api/xxx', //proxy uri
{
headers: {
authorization: ' xxxxxxxxxx' ,
'Content-Type': 'application/json'
}
}).then(function (response) {
console.log(response);
});
run node project node app.js and react project npm start.
Use the google Chrome Extension called Allow-Control-Allow-Origin: *. It modifies the CORS headers on the fly in your application.
I had the same problem. the other answers are correct but there is another solution.
you can set response header to allow cross-origin access.
according to this post you have to add the following codes before any app.get call:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});
this worked for me :)
//install cors using terminal/command
$ npm install cors
//If your using express in your node server just add
var cors = require('cors');
app.use(cors())
//and re-run the server, your problem is rectified][1]][1]
**If you won't be understood then see below image**
https://i.stack.imgur.com/Qeqmc.png
I faced the same error today, using React with Typescript and a back-end using Java Spring boot, if you have a hand on your back-end you can simply add a configuration file for the CORS.
For the below example I set allowed origin to * to allow all but you can be more specific and only set url like http://localhost:3000.
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
#Configuration
public class AppCorsConfiguration {
#Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}
I was having the same problem with the fetch command. A quick look at the docs from here tells us this:
If the server you are requesting from doesn't support CORS, you should get an error in the console indicating that the cross-origin request is blocked due to the CORS Access-Control-Allow-Origin header being missing.
You can use no-cors mode to request opaque resources.
fetch('https://bar.com/data.json', {
mode: 'no-cors' // 'cors' by default
})
.then(function(response) {
// Do something with response
});
You can use this code when using vs code on debugging mode.
"runtimeArgs": ["--disable-web-security","--user-data-dir=~/ChromeUserData/"]
launch.json
{
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "Chrome disable-web-security",
"url": "http://localhost:3000",
"webRoot": "${workspaceFolder}",
"runtimeArgs": [
"--disable-web-security",
"--user-data-dir=~/ChromeUserData/"
]
}
]
}
Or directly run
Chrome --disable-web-security --user-data-dir=~/ChromeUserData/
Create-React-App has a simple way to deal with this problem: add a proxy field to the package.json file as shown below
"proxy": "http://localhost:8081",
I think the answer for your question is here
To have Chrome send Access-Control-Allow-Origin in the header, just alias your localhost in your /etc/hosts file to some other domain, like:
127.0.0.1 localhost yourdomain.com
Because the server don't have CORS header, so you are not allowed to get the response.
This is header from API that I captured from Chrome brower:
Age:28
Cache-Control:max-age=3600, public
Connection:keep-alive
Date:Fri, 06 Jan 2017 02:05:33 GMT
ETag:"18303ae5d3714f8f1fbcb2c8e6499190"
Server:Cowboy
Status:200 OK
Via:1.1 vegur, 1.1 e01a35c1b8f382e5c0a399f1741255fd.cloudfront.net (CloudFront)
X-Amz-Cf-Id:GH6w6y_P5ht7AqAD3SnlK39EJ0PpnignqSI3o5Fsbi9PKHEFNMA0yw==
X-Cache:Hit from cloudfront
X-Content-Type-Options:nosniff
X-Frame-Options:SAMEORIGIN
X-Request-Id:b971e55f-b43d-43ce-8d4f-aa9d39830629
X-Runtime:0.014042
X-Ua-Compatible:chrome=1
X-Xss-Protection:1; mode=block
No CORS header in response headers.
I don't know if this will help but I was getting the same error when remote debugging a react-native application. I was running the debugger on 192.168.x.x:8081. I read a little bit on this Cross-Origin Resource Sharing (CORS) to educate myself on what CORS is. (I'm a beginner) and changed my URL from IP:8081 to localhost:8081 and my issue was resolved.
In my case I was getting the CORS error even after enabling it on server side. The issue was url. localhost:4001/todos I forgot to prepend the 'http'.
http://localhost:4001/todos //correct way
You don't have to deal with it on client side. Just need the following steps:
Step 1:
npm install cors
Step 2:
//express-server.js
...
const cors = require('cors');
app.use(cors());
Done!
This is a common issue occurs when you try to call an endpoint via your react app because react app is running on localhost:3000 and apis are on different servers.
to rectify this error install 'http-proxy-middleware'
npm i http-proxy-middleware
or
yarn add http-proxy-middleware
after installation create a setupProxy.js in your src folder
and follow below code
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/getDetails', //this is your api
createProxyMiddleware({
target:'http://10.0.0.20:9000/getDetails', //this is your whole endpoint link
changeOrigin: true,
})
);
app.use(
'/getproducts', //this is your api
createProxyMiddleware({
target:'http://10.0.0.20:9000/getproducts', //this is your whole endpoint link
changeOrigin: true,
})
);
};
you can add as many api as you want in app.use.
and then just normally call the api
axios.get('http://10.0.0.20:9680/getDetails')
for more details check below link
Porxying API requests in Development in React JS
Add proxy to package.json file and keep the remaining part of url in the fetch itself.
eg.,
In package.json file,
"proxy" : "https://www.google.com", //add your own website link
In App.js file
const response = await fetch(./...(as per your own))
use below after private property in package.json.
"proxy": "http://localhost:5000",
The Key is proxy and the value is your server URL
AND other thing is Chrome does not support localhost to go through the Access-Control-Allow-Origin
chrome isse cors
OR
If you use Express
please add routes after use cors
app.use(cors());
app.use('/posts', postRoutes);
add this to your server.js in your express app
const cors=require("cors");
const corsOptions ={
origin:'*',
credentials:true, //access-control-allow-credentials:true
optionSuccessStatus:200,
}
app.use(cors(corsOptions))
make sure to run npm install cors
I fixed the same problem by simply installing "cors" in my server folder. I used express to create an api and tried to send get request to the api but it did not work without "cors".
I'm using node.js request.js to reach an api. I'm getting this error
[Error: UNABLE_TO_VERIFY_LEAF_SIGNATURE]
All of my credentials are accurate and valid, and the server's fine. I made the same request with postman.
request({
"url": domain+"/api/orders/originator/"+id,
"method": "GET",
"headers":{
"X-API-VERSION": 1,
"X-API-KEY": key
},
}, function(err, response, body){
console.log(err);
console.log(response);
console.log(body);
});
This code is just running in an executable script ex. node ./run_file.js, Is that why? Does it need to run on a server?
Note: the following is dangerous, and will allow API content to be intercepted and modified between the client and the server.
This also worked
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
It's not an issue with the application, but with the certificate which is signed by an intermediary CA.
If you accept that fact and still want to proceed, add the following to request options:
rejectUnauthorized: false
Full request:
request({
"rejectUnauthorized": false,
"url": domain+"/api/orders/originator/"+id,
"method": "GET",
"headers":{
"X-API-VERSION": 1,
"X-API-KEY": key
},
}, function(err, response, body){
console.log(err);
console.log(response);
console.log(body);
});
The Secure Solution
Rather than turning off security you can add the necessary certificates to the chain. First install ssl-root-cas package from npm:
npm install ssl-root-cas
This package contains many intermediary certificates that browsers trust but node doesn't.
var sslRootCAs = require('ssl-root-cas/latest')
sslRootCAs.inject()
Will add the missing certificates. See here for more info:
https://git.coolaj86.com/coolaj86/ssl-root-cas.js
CoolAJ86's solution is correct and it does not compromise your security like disabling all checks using rejectUnauthorized or NODE_TLS_REJECT_UNAUTHORIZED. Still, you may need to inject an additional CA's certificate explicitly.
I tried first the root CAs included by the ssl-root-cas module:
require('ssl-root-cas/latest')
.inject();
I still ended up with the UNABLE_TO_VERIFY_LEAF_SIGNATURE error. Then I found out who issued the certificate for the web site I was connecting to by the COMODO SSL Analyzer, downloaded the certificate of that authority and tried to add only that one:
require('ssl-root-cas/latest')
.addFile(__dirname + '/comodohigh-assurancesecureserverca.crt');
I ended up with another error: CERT_UNTRUSTED. Finally, I injected the additional root CAs and included "my" (apparently intermediary) CA, which worked:
require('ssl-root-cas/latest')
.inject()
.addFile(__dirname + '/comodohigh-assurancesecureserverca.crt');
For Create React App (where this error occurs too and this question is the #1 Google result), you are probably using HTTPS=true npm start and a proxy (in package.json) which goes to some HTTPS API which itself is self-signed, when in development.
If that's the case, consider changing proxy like this:
"proxy": {
"/api": {
"target": "https://localhost:5001",
"secure": false
}
}
secure decides whether the WebPack proxy checks the certificate chain or not and disabling that ensures the API self-signed certificate is not verified so that you get your data.
It may be very tempting to do rejectUnauthorized: false or process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0'; but don't do it! It exposes you to man in the middle attacks.
The other answers are correct in that the issue lies in the fact that your cert is "signed by an intermediary CA." There is an easy solution to this, one which does not require a third party library like ssl-root-cas or injecting any additional CAs into node.
Most https clients in node support options that allow you to specify a CA per request, which will resolve UNABLE_TO_VERIFY_LEAF_SIGNATURE. Here's a simple example using node's built-int https module.
import https from 'https';
const options = {
host: '<your host>',
defaultPort: 443,
path: '<your path>',
// assuming the bundle file is co-located with this file
ca: readFileSync(__dirname + '/<your bundle file>.ca-bundle'),
headers: {
'content-type': 'application/json',
}
};
https.get(options, res => {
// do whatever you need to do
})
If, however, you can configure the ssl settings in your hosting server, the best solution would be to add the intermediate certificates to your hosting provider. That way the client requester doesn't need to specify a CA, since it's included in the server itself. I personally use namecheap + heroku. The trick for me was to create one .crt file with cat yourcertificate.crt bundle.ca-bundle > server.crt. I then opened up this file and added a newline after the first certificate. You can read more at
https://www.namecheap.com/support/knowledgebase/article.aspx/10050/33/installing-an-ssl-certificate-on-heroku-ssl
You can also try by setting strictSSL to false, like this:
{
url: "https://...",
method: "POST",
headers: {
"Content-Type": "application/json"},
strictSSL: false
}
I had the same issues. I have followed #ThomasReggi and #CoolAJ86 solution and worked well but I'm not satisfied with the solution.
Because "UNABLE_TO_VERIFY_LEAF_SIGNATURE" issue is happened due to certification configuration level.
I accept #thirdender solution but its partial solution.As per the nginx official website, they clearly mentioned certificate should be combination of The server certificate and chained certificates.
Just putting this here in case it helps someone, my case was different and a bit of an odd mix. I was getting this on a request that was accessed via superagent - the problem had nothing to do with certificates (which were setup properly) and all to do with the fact that I was then passing the superagent result through the async module's waterfall callback. To fix: Instead of passing the entire result, just pass result.body through the waterfall's callback.
Following commands worked for me :
> npm config set strict-ssl false
> npm cache clean --force
The problem is that you are attempting to install a module from a repository with a bad or untrusted SSL[Secure Sockets Layer] certificate. Once you clean the cache, this problem will be resolved.You might need to turn it to true later on.
Another approach to solving this securely is to use the following module.
node_extra_ca_certs_mozilla_bundle
This module can work without any code modification by generating a PEM file that includes all root and intermediate certificates trusted by Mozilla. You can use the following environment variable (Works with Nodejs v7.3+),
NODE_EXTRA_CA_CERTS
To generate the PEM file to use with the above environment variable. You can install the module using:
npm install --save node_extra_ca_certs_mozilla_bundle
and then launch your node script with an environment variable.
NODE_EXTRA_CA_CERTS=node_modules/node_extra_ca_certs_mozilla_bundle/ca_bundle/ca_intermediate_root_bundle.pem node your_script.js
Other ways to use the generated PEM file are available at:
https://github.com/arvind-agarwal/node_extra_ca_certs_mozilla_bundle
NOTE: I am the author of the above module.
I had an issue with my Apache configuration after installing a GoDaddy certificate on a subdomain. I originally thought it might be an issue with Node not sending a Server Name Indicator (SNI), but that wasn't the case. Analyzing the subdomain's SSL certificate with https://www.ssllabs.com/ssltest/ returned the error Chain issues: Incomplete.
After adding the GoDaddy provided gd_bundle-g2-g1.crt file via the SSLCertificateChainFile Apache directive, Node was able to connect over HTTPS and the error went away.
If you come to this thread because you're using the node postgres / pg module, there is a better solution than setting NODE_TLS_REJECT_UNAUTHORIZED or rejectUnauthorized, which will lead to insecure connections.
Instead, configure the "ssl" option to match the parameters for tls.connect:
{
ca: fs.readFileSync('/path/to/server-ca.pem').toString(),
cert: fs.readFileSync('/path/to/client-cert.pem').toString(),
key: fs.readFileSync('/path/to/client-key.pem').toString(),
servername: 'my-server-name' // e.g. my-project-id/my-sql-instance-id for Google SQL
}
I've written a module to help with parsing these options from environment variables like PGSSLROOTCERT, PGSSLCERT, and PGSSLKEY:
https://github.com/programmarchy/pg-ssl
Hello just a small adition to this subject since in my case the
require('ssl-root-cas/latest')
.inject()
.addFile(__dirname + '/comodohigh-assurancesecureserverca.crt');
didn't work out for me it kept returning error that the file could not be downloaded i had been a couple of hours into the reasearch of this particular error when I ran into this response https://stackoverflow.com/a/65442604
Since in my application we do have a proxy to proxy some of our requests as a security requirement of some of our users I found that in the case you are consulting an API that has this issue and if you can access the API url throught your browser you can proxy your request and it might fix the [Error: UNABLE_TO_VERIFY_LEAF_SIGNATURE] issue.
An example of how i use my proxy
await axios.get(url, {
timeout: TIME_OUT,
headers: {
'User-Agent': 'My app'
},
params: params,
proxy: {
protocol: _proxy.protocol,
host: _proxy.hostname,
port: _proxy.port,
auth: {
username: _proxy_username,
password: _proxy_password
}
}
});
I had the same problem and I am able to fix it the following way,
Use the full-chain or just the chain certificate instead of just the certificate.
That is all.
This same error can be received when trying to install a local git shared repo from npm.
The error will read: npm ERR! code UNABLE_TO_VERIFY_LEAF_SIGNATURE
Apparently there is an issue with the certificate, however what worked for me was change the link to my shared repo in the package.json file from:
"shared-frontend": "https://myreposerver"
to:
"shared-frontend": "git+https://myreposerver"
In short, just adding git+ to the link solved it.
Another reason node could print that error is because a backend connection/service is misconfigured.
Unfortunately, the node error doesn't say which certificate it was unable to verify [feature request !]
Your server may have a perfectly good certificate chain installed for clients to connect and even show a nice padlock in the browser's URL bar, but when the server tries to connect to a backend database using a different misconfigured certificate, then it could raise an identical error.
I had this issue in some vendor code for some time. Changing a backend database connection from self-signed to an actual certificate resolved it.
You have to include the Intermediate certificate in your server. This solves the [Error: UNABLE_TO_VERIFY_LEAF_SIGNATURE]