Access to XMLHttpRequest blocked by CORS Policy in ReactJS using Axios - reactjs

I'm setting up stripe connect button in my React Component using Axios. I keep getting this error after redirection
Access to XMLHttpRequest at 'https://connect.stripe.com/oauth/token' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.
Thankyou.js:40 Error: Network Error
at createError (createError.js:16)
at XMLHttpRequest.handleError (xhr.js:87)
I get the code from the url and create a curl request using axios.Post. This is the code in my redirect URL
// Thankyou.js
export default class Thankyou extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
const code = qs.parse(this.props.location.search, {
ignoreQueryPrefix: true
}).code;
const params = {
client_id: "*******************",
client_secret: "**********************",
grant_type: "authorization_code",
code: code
};
axios
.post(
"https://connect.stripe.com/oauth/token",
// apiBaseUrl,
{ params }
)
.then(function(response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
});
console.log(code);
}
render() {
return (
<div>
<h2>Thank you for connecting with us!</h2>
</div>
);
}
}

There is nothing wrong with your code, but most likely the API endpoint the code trying to reach is not setup for JavaScript web app. CORS policy is set on the server-side and enforced primarily on the browser-side.
The best way to work around is to use Stripe's JavaScript solution such as Strip React Elements or Stripe.js.
A hacky way to get around CORS would be setting up Reverse proxy with solutions such as NGINX. For example, you can use the following nginx configuration:
server {
listen 8080;
server_name _;
location / {
proxy_pass http://your-web-app:2020/;
}
location /stripe/ {
proxy_pass https://connect.stripe.com/;
}
}
By doing so, all the API calls to Stripe.com could be through /stripe under your web app's URL. For example, calling http://yourapp/stripe/oauth/token would be same as calling https://connect.stripe.com/oauth/token
That being said, the second solution is hacky and Stripe may decide to block your reverse proxy server.

basically you need to talk to whoever is hosting this https://connect.stripe.com/oauth/token to enable CORS (Cross Origin Resource Sharing )
It is a security measure implemented by most standard browsers to stop unwanted requests to your backend

It's probably because Stripe doesn't provide JavaScript client so you either have to use your own server proxy or use something like "https://cors-anywhere.herokuapp.com/https://connect.stripe.com/oauth/token"

I hope this answer would be useful to new users:
This issue can be easily fixed by using an annotation in your spring boot rest controller class.
Something like below (also ref screenshot):
#CrossOrigin(origins = "http://localhost:4200")
Explicitly mention the react JS server URL that is causing this issue.
Now after adding above annotation (with your react JS server URL) the browser will allow the flow.
All the best.

Learn about CORS
Think about it, there is anything wrong with your axios.post request, it's successfully contacting the server. But there is one more thing to do before the server let you execute or manipulate it's files.
For security reasons, browsers restrict cross-origin HTTP requests initiated from within scripts. For example, XMLHttpRequest and the Fetch API follow the same-origin policy.
So your cross-origin request and the server Cross-Origin Resource Sharing (CORS) have to match.
How do you solve it?
Depending on your server and the server side programming language your are implementing, you can configure the different parameters to handle your CORS.
For example, you can configure that the only allowed methods will be:
GET HEAD
So if someone try to axios.post to your server with a different method like POST, it will return an error like this:
Access to XMLHttpRequest at 'https://connect.stripe.com/oauth/token' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.
Thankyou.js:40 Error: Network Error
at createError (createError.js:16)
at XMLHttpRequest.handleError (xhr.js:87)
Resources:
https://www.w3.org/TR/cors/
https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

I would suggest reading through this site: https://stripe.com/docs/recipes/elements-react
It gives specific instructions straight from stripe on using their API with react. Good luck!

Related

CORS Not Working - No Access-Control-Allow-Origin' header

thank you for taking a look at my question. I have been building my flask app to help deliver some calculatoins in python to my React front end. I am attempting to bridge the gap between the two different servers but am having trouble with CORS (from the looks of it along with many others new to flask with react)
I have tried to change around many things like adding #cross_origin, origins: '', and headers.add("Access-Control-Allow-Origin", "") but no success. All I need from flask is the result of my functions. Has anyone else run into an issue similar or know a way I can fix this?
Flask Code:
app = Flask(__name__)
CORS(app, resources={r"/*": {"origins": "*", "allow_headers": "*", "expose_headers": "*"}})`
#app.route('/')
#cross_origin()
def welcome():
response = jsonify({'reply': 'Hello Webminers'})
response.headers.add("Access-Control-Allow-Origin", "*")
return response
React Code:
console.log(axios.get('http://127.0.0.1:5000'))
Console:
Access to XMLHttpRequest at 'http://127.0.0.1:5000/' from origin 'http://localhost:3000' has been
blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested
resource.
Failed to load resource: net::ERR_FAILED
P.S not sure if this matters or not but I have also gotten the same response with 'localhost:5000 from origin localhost:3000'
Edit:
axios.get('http://127.0.0.1:5000', {headers: {"Access-Control-Allow-
Origin": "*"}}).then(response => {
console.log(response.data);
})
I added this in and got this new response from the console
Access to XMLHttpRequest at 'http://127.0.0.1:5000/' 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
I believe that I found the issue. I was looking around and trying a bunch of different things and even attempted to recreate the API in fastAPI to reach the same results.
However, I have just found this comment stating that they had an issue where React would be running but leaving the API behind thus causing errors for not being able to get the data from my API. https://stackoverflow.com/a/58786845/19683392
I am currently still looking for the solution and may open a new question but for now, I am getting this error:
TypeError: NetworkError when attempting to fetch resource.
More updates soon...
*** Edit ***
FOUND IT!
Bam fixed it with the concurrent library's help
"start": "concurrently \"react-scripts start\"
\"flask --app Backend/FlaskAPI.py run\"",
Is the config I used for anyone else who runs into the same issue
You don't need to manually set the header, the CORS package will handle that for you. Also in frontend you don't need to specify CORS header when calling the API
Can you try the following way?
app = Flask(__name__)
CORS(app)
#app.route('/')
#cross_origin()
def welcome():
response = jsonify({'reply': 'Hello Webminers'})
return response
Then access the api like this:
axios.get('http://127.0.0.1:5000').then(response => {
console.log(response.data);
})

Why React can't reach Flask endpoints in production?

I've got a React app with Flask on the backend in production and I found out
that none of my endpoints are reached from React.
I'm aware that when using client-side routing developer needs to use a catch-all function
similar to the below:
#app.errorhandler(404)
def error_handler(e):
return render_template('index.html')
I'm using Flask-CORS to handle cross origin requests:
within config.py:
class ProductionConfig:
CORS_HEADERS = 'Content-Type'
...
...
my blueprint:
CORS(auth_blueprint, resources={r'/*': {"origins": "https://example.com", "allow_headers": "*", "expose_headers": "*"}})
#auth_blueprint.route('/auth/login', methods=['POST'])
#cross_origin()
def login():
...
...
on the frondend I'm defining headers like this:
const headers = { "Access-Control-Allow-Origin": "*" };
const url = "https://example.com:5000/auth/login";
axios.post(url, data, headers).then(resp => { ... })
And I'm not getting any errors whatsoever. Server's logs are clean and the console only shows Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://example.com:5000/auth/login. (Reason: CORS request did not succeed).
"Reason: CORS request did not succeed" means that the server didn't return anything.
The app renders fine however React (axios) can't reach my endpoints. Are there any gotchas I'm not aware of ? When request is sent I'm not even getting a status code in the network tab.
Thank you.
Screenshot of the network tab:
You need to change the connection protocol to http.

CORS error on Axios PUT request from React to Spring API

I am working on an update functionality using PUT. I have a React front end and Spring back-end API. Here is the following PUT request made from front-end:
updateStuff(username, id, stuff){
return Axios.put(`http://localhost:8080/stuff/${username}`, {stuff})
}
Controller to handle this request:
#RestController
#CrossOrigin(origins="http://localhost:3000")
public class StuffController {
#Autowired
private StuffService stuffService;
#PutMapping(path="/stuff/{username}/{id}")
public ResponseEntity<Stuff> updateStuff(#PathVariable String username,
#PathVariable long id,
#RequestBody Stuff stuff) {
Stuff response = stuffService.save(stuff);
return new ResponseEntity<Stuff>(stuff, HttpStatus.OK);
}
I am able to use the same service for GET and DELETE. I am also able to send request using REST client. But when I am trying using browser I am getting this error in console:
Access to XMLHttpRequest at 'http://localhost:8080/stuff/abc' 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.
PUT http://localhost:8080/stuff/abc net::ERR_FAILED
Not able to figure out why its just happening for PUT request? How to resolve this? Appreciate your help and time!
EDIT:
Updated the front-end to:
updateStuff(username, id, stuff){
return Axios.put(`http://localhost:8080/stuff/${username}`, {
headers:{
'Access-Control-Allow-Origin':'*',
'Content-Type': 'application/json;charset=UTF-8',
}
})
}
Still its throwing the same error. So far Spring Security is not configured. I am just checking a simple update flow without any authentication or authorization.
EDIT 2: Request headers in browser has Access-Control-Allow-Origin: *:
I ran into a similar issue a while ago. Check if the variables of your model class in the backend have the same name as in your frontend. That fixed it for me.
The best way to deal with this cors policy is to add a proxy field in the pakage.json file.enter image description here
In reactjs application you can use your spring boot api's URL as proxy to avoid CORS issue.
package.
package.json
{
"proxy": "http://localhost:8080/",
"dependencies": {
.
.
.
}
}
axios
Axios.put(stuff/${username}, {stuff})

CORS request did not succeed - react

I make this API request , using axios in ReactJS
axios.post(`${API_URL}/valida_proximo`, {
id: images.map(image => image.id)
},
getAxiosConfig())
// this.setState({ images, loadingAtribuiImagens: false})
}
It works really well in Google Chrome, but on Firefox I receive an error:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:5000/valida_proximo. (Reason: CORS request did not succeed).[Learn More]
What can I do?
This is my API
#blueprint.route('', methods=['POST', ])
#jwt_required()
def index():
if request.json:
id_usuarioImagem = request.json.get('id')
imagens_selecionadas =
UsuarioImagem.query.filter(UsuarioImagem.id.in_(id_usuarioImagem)).all()
if imagens_selecionadas:
for imagem_selecionada in imagens_selecionadas:
imagem_selecionada.batido=True
db.session.commit()
return 'ok', 200
return 'error', 400
CORS errors are usually associated with cross domain requests and something not configured to accept a request on the recipient side of the request. The fact that chrome is working but firefox doesn't seems rather strange.
This was a method I used:
Open Firefox browser and load the page.
Perform the operation which is throwing Cross Origin Request Security (CORS) error.
Open firebug and copy the URL which is throwing Cross Origin Request Security (CORS) error.
Load the same URL in another tab in same Firefox browser.
Once you open the URL in another tab will ask you to add the certificate.
After adding the certificate will resolve Cross Origin Request Security (CORS) error and now you will not be getting this error.
I'm not too familiar with Axios, but it looks like you're making a post request from your React to your Flask backend. If the front-end and the backend are on different ports (like your Flask seems to be on PORT 5000), then you're making a CORS request.
With CORS, depending on what you're posting, you might need to include some Access-Control headers in your Flask response object. You can do this either manually, or just pip-installing and using the 'flask-cors' package. Import the package into your app factory and use it like so (see their docuementation for more info):
from flask_cors import CORS
def create_app(test_config=None):
app = Flask(__name__, instance_relative_config=True)
CORS(app)
The request might also get 'preflighted' with an 'OPTIONS' request, also depending on the nature of your POST. More information would be helpful
This is a bug in firefox.
if you follow the link (MDN) in the error msg . you will find:
What went wrong?
The HTTP request which makes use of CORS failed because the HTTP connection failed at either the network or protocol level. The error is not directly related to CORS, but is a fundamental network error of some kind.
which i read as the connection failed and not a problem with CORS settings.
you will just have to ignore the error message until firefox gets it fixed.
The error has something to do with refreshing the page and long polling requests or service workers and polling requests.
If anyone sees this question again, I had this problem because I made a request to https://url instead of http://url

How do I get react-stormpath to add Access-Control-Allow-Origin headers?

I'm having a similar problem to:
401 Error with post request Stormpath Express + React + Node + Gulp
Specifically, when I try to use the LoginForm or RegisterForm from react-stormpath, I get:
XMLHttpRequest cannot load https://api.stormpath.com/v1/applications/[ID]/oauth/token. 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 401.
I have added http://localhost:3000 to the Authorized Origin URIs in the Stormpath console, but that doesn't help. I've inspected the request using Chrome, and indeed, there is no ACAO header coming back.
Unlike the other issue linked to above, I'm not doing anything custom. My login page just looks like this:
import React from 'react';
import { LoginForm } from 'react-stormpath';
export default class Login extends React.Component {
render() {
return (
<LoginForm />
);
}
}
I don't even know how to debug this issue because I don't know what's going on under the hood in react-stormpath.
Edit: Adding the react-stormpath config:
ReactStormpath.init({
endpoints: {
baseUri: 'https://api.stormpath.com/v1/applications/[ID]'
}
});
The problem is in your ReactStormpath.init. Your React app can't connect to api.stormpath.com directly, because that requires using a secure API key. Your baseUri should instead be one of:
Your Stormpath application's Client API URL, like https://foo-bar.apps.stormpath.io. This is a separate API domain that allows untrusted clients (like React) to connect. This part of the documentation is a better example.
Your web server, like http://localhost:3000 - if you are using something like express-stormpath (I can't quite tell from your question)
Disclaimer: I work at Stormpath.

Resources