Cors origin React Api plateform - reactjs

I have a REST API with symfony/api-plateform on port 8000 and front app React on port 3000
In my React App: I want to get file with url
let url = 'http://localhost:8000/delivrables/school/2021/b1_cpd/homework_matiere_0__devoir_0/picard-%C3%89lisabeth.zip'
axios.get(url)
.then(res => {
console.log(res)
})
but I get a CORS error :
Access to XMLHttpRequest at 'http://localhost:8000/delivrables/school/2021/b1_cpd/homework_matiere_0__devoir_0/picard-%C3%89lisabeth.zip' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
react_devtools_backend.js:4049
I have configurated my app symfony/api-plateform for cors :
CORS_ALLOW_ORIGIN=^https?://.*?$
When I call this URL (for exemple) with postman (http://localhost:8000/delivrables/school/2021/b1_cpd/homework_matiere_0__devoir_0/picard-%C3%89lisabeth.zip) that work.
Try with header (not work) :
axios(url, {
method: 'GET',
headers: {
'Access-Control-Allow-Origin': '*',
}
}).then(response => {
console.log(response)
})
nelmio_cors.yml
nelmio_cors:
defaults:
origin_regex: true
allow_origin: ['*']
allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
allow_headers: ['Content-Type', 'Authorization']
expose_headers: ['Link']
max_age: 3600
hosts: []
paths:
'^/':
origin_regex: true
allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']
allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
allow_headers: ['X-Custom-Auth']
max_age: 3600
hosts: ['^api\.']

You can try adding this to your React project's package.json
"proxy": "http://localhost:8000"
But of course this will work just for this dev server setup, not for production.
And also in this case you should use "relative" url in your request, that is starting with /delivrables...

Related

Unable to upload images to AWS S3 from React App

I want to upload images to AWS S3 from my React app directly using aws-sdk.
I have setup my S3 bucket with the following policies -
Bucket Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicRead",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:DeleteObject",
"s3:GetObject",
"s3:ListBucket",
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": [
"arn:aws:s3:::<my-bucket-name>",
"arn:aws:s3:::<my-bucket-name>/*"
]
}
]
}
CORS Policy:
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"HEAD",
"GET",
"PUT",
"POST",
"DELETE"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": [
"ETag"
]
}
]
In my React app I'm using aws-sdk to upload images to S3. I have the following function -
export const uploadToS3 = (file: any) => {
AWS.config.update({
accessKeyId: S3_ACCESS_KEY,
secretAccessKey: S3_SECRET_KEY,
});
const bucket = new AWS.S3({
params: { Bucket: S3_BUCKET_NAME },
region: S3_REGION,
});
const params: any = {
ACL: "public-read",
Body: file,
Bucket: S3_BUCKET_NAME,
Key: file.name,
};
bucket
.putObject(params)
.on("httpUploadProgress", (e) => {
console.log(Math.round((e.loaded / e.total) * 100));
})
.send((error: any) => {
if (error) console.log(error);
});
};
I still get a CORS error -
Access to fetch at 'https://tribeone-nonceblox.s3-ap-south-1.amazonaws.com/' from origin 'http://localhost:3000' has been blocked by CORS policy: 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.
What should I do?

Axios call getting blocked due to CORS error

I have a react application with server side rendering using Express server . I want to make a POST request using axios but it is getting blocked with CORS error :
"Access to XMLHttpRequest at 'https://xyz/abc' from origin 'http://localhost:4249' 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 have tried after adding allow origin headers and cors module in my server call but that didn't work
import cors from "cors";
const server = express();
server.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-Allow-Methods",
"OPTIONS, GET, POST, PUT, PATCH, DELETE"
);
res.header("Access-Control-Allow-Headers", "Content-Type, Authorization");
next();
});
server.use(express.static("dist"));
server.use(cors());
Here is the axios request :
const headers = {
Accept: "application/json",
"x-ms-version": "2019-07-11",
Authorization: token,
"x-ms-date": date,
"x-ms-documentdb-isquery": true,
"Content-Type": "application/query+json",
"x-ms-documentdb-query-enablecrosspartition": "true",
"cache-control": "no-cache",
"Access-Control-Allow-Origin": "*",
};
useEffect(() => {
axios
.post(
"https://xyz/abc",
data,
{
headers: headers,
}
)
.then(function (response) {
setres(response.data);
})
.catch(function (error) {
console.log(error);
});
}, []);
Webpack Config:
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
},
},
{
test: /\.(sass|css|scss)$/,
use: ["style-loader", "css-loader"],
},
],
},
};
I have encountered this problem before, and this is just what I did:
app.js (backend)
server.use(cors({
origin: '<YOUR_FRONTEND_URL_PATH>',
methods: 'GET,HEAD,POST,PUT,DELETE',
preflightContinue: false,
credentials: true
}));
axios request:
const resp = await axios.post(
apiUrl,
params,
{
withCredentials: true,
timeout: 10000
}
);

The JWT is not available in the response Authorization header, but present in the Network tab

I have a Spring Boot app as a back-end API and a React app as a front end.
CORS is enabled in the Spring Boot and I use axios to send requests to the Spring Boot API.
When calling '/login', Spring Boot security kicks in and produces a JWT
token, which is passed back to ReactJS as the Authorization header. The
issue is that this header does not appear in the response received in the
React app then processing block. It does show correctly in the Developer
Tools Network tab. Below is the relevant code:
axios.post("http://localhost:8080/login", LoginRequest)
.then(response => {console.log("RRR ", response)});
The console output is as follows:
{data: "", status: 200, statusText: "", headers: {…}, config: {…}, …}
config:
adapter: ƒ xhrAdapter(config)
data: "{"username":"test#test.com","password":"test$2"}"
headers:
Accept: "application/json, text/plain, */*"
Content-Type: "application/json;charset=utf-8"
__proto__: Object
maxContentLength: -1
method: "post"
timeout: 0
transformRequest: {0: ƒ}
transformResponse: {0: ƒ}
url: "http://localhost:8080/login"
validateStatus: ƒ validateStatus(status)
xsrfCookieName: "XSRF-TOKEN"
xsrfHeaderName: "X-XSRF-TOKEN"
__proto__: Object
data: ""
headers: {pragma: "no-cache", cache-control: "no-cache, no-store, max-age=0, must-revalidate", expires: "0"}
request: XMLHttpRequest {onreadystatechange: ƒ, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}
status: 200
statusText: ""
What am I missing?

webpack dev server CORS issue

I am using webpack-dev-server v1.10.1 to boost up my Redux project and I have the options below:
contentBase: `http://${config.HOST}:${config.PORT}`,
quiet: false,
noInfo: true,
hot: true,
inline: true,
lazy: false,
publicPath: configWebpack.output.publicPath,
headers: {"Access-Control-Allow-Origin": "*"},
stats: {colors: true}
In the JS, I am using request from superagent to generate a HTTP GET call
request
.get(config.APIHost + apiUrl)
.set('Accept', 'application/json')
.withCredentials()
.end(function (err, res) {
if (!err && res.body) {
disptach(() => {
return {
type: actionType || GET_DATA,
payload: {
response: res.body
}
}
});
}
});
But I got the CORS error:
XMLHttpRequest cannot load http://localhost:8000/api/getContentByType?category=all. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:5050' is therefore not allowed access
Any suggestion to resolve this? Thanks a lot
Another way to work around it is to directly add the required CORS headers to the dev server:
devServer: {
...
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
"Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"
}
}
Doc links
Webpack dev server
Access-Control-Allow-Headers
Access-Control-Allow-Methods
Access-Control-Allow-Origin
With webpack-dev-server 1.15.X you can use this configuration in your config file:
devServer: {
contentBase: DIST_FOLDER,
port: 8888,
// Send API requests on localhost to API server get around CORS.
proxy: {
'/api': {
target: {
host: "0.0.0.0",
protocol: 'http:',
port: 8080
},
pathRewrite: {
'^/api': ''
}
}
}
},
With this example you will redirect all calls from http://0.0.0.0:8888/api/* to http://0.0.0.0:8080/* and CORS solved
Had the same issue, but my api was on a https protocol (https://api....). Had to start the server with https and use https://localhost:8080
devServer: {
https: true,
headers: {
"Access-Control-Allow-Origin": "*",
},
// ....
}
You're running your JavaScript from localhost:5050 but your API server is localhost:8000. This violates the same origin policy, so the browser disallows it.
You can either modify your API server so that CORS is enabled, or follow the instructions on the webpack-dev-server page under "Combining with an existing server" to combine asset serving with webpack-dev-server and your own API server.
There are 2 solutions for this. first one is setting up proxy on the client side, second one is setting CORS on the server. CORS is server issue, server does not allow access from different source. Even using different ports is considered to be different source
First Solution
IN your backend code, you have to set this headers: this is example of in express node.js
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Methods",
"OPTIONS, GET, POST, PUT, PATCH, DELETE"
);
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
next();
});
Second Solution:
in webpack config.js, if you want to pass any variable, we export
module.exports=function(env){
return {}}
instead of
module.exports={}
we inject this env through the script.
"dev-server": "webpack-dev-server --env.api='https://jsonplaceholder.typicode.com/users'",
now webpack has access to this env. in webpack.config.js
module.exports = function ({
api = "https://jsonplaceholder.typicode.com/users",
}) {
return {
entry: { main: "./src/index.js" },
output: {
path: path.resolve(__dirname, "public"),
filename: "[name]-bundle.js",
publicPath: "/",
},
mode: "development",
module: {
rules: [
{
loader: "babel-loader",
test: /\.js$/,
exclude: [/node_modules/],
},
{
// Load other files, images etc
test: /\.(png|j?g|gif|ico)?$/,
use: "url-loader",
},
{
test: /\.s?css$/,
use: ["style-loader", "css-loader", "sass-loader"],
},
],
},
//Some JavaScript bundlers may wrap the application code with eval statements in development.
//If you use Webpack, using the cheap-module-source-map setting in development to avoid this problem
devtool: "cheap-module-eval-source-map",
devServer: {
contentBase: path.join(__dirname, "public"),
historyApiFallback: true,
proxy: {
"/api": {
changeOrigin: true,
cookieDomainRewrite: "localhost",
target: api,
onProxyReq: (proxyReq) => {
if (proxyReq.getHeader("origin")) {
proxyReq.setHeader("origin", api);
}
},
},
},
},
};
};

Grunt Connect Proxy not sending POST Parameters

I have an my app configured to use grunt-connect-proxy. Request reach the server and evverything is working fine apart from POST requests.
When running grunt with the verbose option set, I can see:
Proxied request: /api/data.json -> http://myProdutionDomain.com:80/beta/api/data.json
{
"host": "0.0.0.0:9000",
"connection": "keep-alive",
"content-length": "15",
"accept": "application/json, text/plain, */*",
"origin": "http://0.0.0.0:9000",
"user-agent": "Mozilla/5.0 (Macintosh; ...)",
"content-type": "application/json;charset=UTF-8",
"referer": "http://0.0.0.0:9000/",
"accept-encoding": "gzip,deflate,sdch",
"accept-language": "en",
"cookie": "some-cookie",
}
My proxies configuration is as follows:
proxies: [
{
context: '/api',
host: 'myProdutionDomain.com',
changeOrigin: true,
rewrite: {
'^/': '/beta/'
}
}
]
From Angular I just do:
$http.post(requestUrl, {'id': id});
Also tried:
request = $http.post(requestUrl, {'id': id}, {'headers': {'Content-Type': 'application/x-www-form-urlencoded'}});
Problem is the 'id' post param is never sent to the server.
Anyone has experience with this?

Resources